목표
고객(순구매자) 데이터를 타겟 변수로 지정 (Purchased)진행 계획
순 구매 테이블)import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
# %matplotlib inline
# 주피터 노트북에 최적화 된 그래프 설정(코랩 사용불가)
# %matplotlib notebook
# 인터렉티브 그래프 가능(코랩 사용불가)
%config InlineBackend.figure_format = 'retina'
주피터 노트북 matplotlib 한글 설정
# import os
# # Mac OS의 경우와 그 외 OS의 경우로 나누어 설정
# if os.name == 'posix':
# plt.rc("font", family="AppleGothic")
# else:
# plt.rc("font", family="Malgun Gothic")
코랩 matplotlib 한글 설정
# 네이버 나눔 폰트 설치
#!sudo apt-get install -y fonts-nanum
#!sudo fc-cache -fv
#!rm ~/.cache/matplotlib -rf
# 실행 후 런타입 재실행
Reading package lists... Done Building dependency tree Reading state information... Done The following package was automatically installed and is no longer required: libnvidia-common-460 Use 'sudo apt autoremove' to remove it. The following NEW packages will be installed: fonts-nanum 0 upgraded, 1 newly installed, 0 to remove and 42 not upgraded. Need to get 9,604 kB of archives. After this operation, 29.5 MB of additional disk space will be used. Get:1 http://archive.ubuntu.com/ubuntu bionic/universe amd64 fonts-nanum all 20170925-1 [9,604 kB] Fetched 9,604 kB in 1s (18.0 MB/s) debconf: unable to initialize frontend: Dialog debconf: (No usable dialog-like program is installed, so the dialog based frontend cannot be used. at /usr/share/perl5/Debconf/FrontEnd/Dialog.pm line 76, <> line 1.) debconf: falling back to frontend: Readline debconf: unable to initialize frontend: Readline debconf: (This frontend requires a controlling tty.) debconf: falling back to frontend: Teletype dpkg-preconfigure: unable to re-open stdin: Selecting previously unselected package fonts-nanum. (Reading database ... 155629 files and directories currently installed.) Preparing to unpack .../fonts-nanum_20170925-1_all.deb ... Unpacking fonts-nanum (20170925-1) ... Setting up fonts-nanum (20170925-1) ... Processing triggers for fontconfig (2.12.6-0ubuntu2) ... /usr/share/fonts: caching, new cache contents: 0 fonts, 1 dirs /usr/share/fonts/truetype: caching, new cache contents: 0 fonts, 3 dirs /usr/share/fonts/truetype/humor-sans: caching, new cache contents: 1 fonts, 0 dirs /usr/share/fonts/truetype/liberation: caching, new cache contents: 16 fonts, 0 dirs /usr/share/fonts/truetype/nanum: caching, new cache contents: 10 fonts, 0 dirs /usr/local/share/fonts: caching, new cache contents: 0 fonts, 0 dirs /root/.local/share/fonts: skipping, no such directory /root/.fonts: skipping, no such directory /var/cache/fontconfig: cleaning cache directory /root/.cache/fontconfig: not cleaning non-existent cache directory /root/.fontconfig: not cleaning non-existent cache directory fc-cache: succeeded
# 런타임 재실행 후 적용
plt.rc('font', family='NanumBarunGothic')
엑셀 불러오기 설정
!pip install openpyxl
Requirement already satisfied: openpyxl in /usr/local/lib/python3.7/dist-packages (3.0.9) Requirement already satisfied: et-xmlfile in /usr/local/lib/python3.7/dist-packages (from openpyxl) (1.1.0)
테이블 시트 위치 설정
%%html
<style>
table {margin-left: 0 !important;}
</style>
-Columns
| Columns | Content |
|---|---|
| id | 해당 거래내역에 대한 ID(PK) |
| customer_id | 결제한 고객 ID |
| course_id | 강의 ID (프로모션에 대해서는 값이 할당X) |
| type | 거래의 종류 |
| state | 거래에 대한 상태 |
| course_title | 강의 제목 |
| category_title | 대분류 |
| format | 온라인 강의의 기획 종류 |
| completed_at | state가 COMPLETED로 변경된 시점 |
| transaction_amount | 최종 결제 금액 |
| coupon_title | 쿠폰 종류 |
| coupon_discount_amount | 쿠폰 할인 금액 |
| sale_price | 판매 금액 |
| tax_free_amount | 보안상 공유가 힘듦 |
| pg | PG사 종류 |
| method | 결제 방식 |
| subcategory_title | 중분류 |
| marketing_start_at | 강의 판매 시점 |
-Type 유형
| type | 유형 |
|---|---|
| ORDER | DEPRECATED |
| PAYMENT | 결제 |
| TRANSACTION | B2B 계약결제(무시해도 좋음) |
| REFUND | 환불 |
-State 유형
| state | 상태 |
|---|---|
| COMPLETED | 결제 완료 |
| REQUESTED | 고객에게 결제 요청 |
| PENDING | 보안 이슈로 공개X |
| CANCELLED | 보안 이슈로 공개X |
| HIDDEN | 보안 이슈로 공개X |
| DELETE | 보안 이슈로 공개X |
# 데이터 불러오기
# for colab
from google.colab import drive
drive.mount('/content/drive')
Mounted at /content/drive
train = pd.read_excel("/content/drive/MyDrive/Colab Notebooks/yds/FC_EDA/파이널프로젝트_RAW_210329_210926.xlsx")
df = train.copy()
df.head()
| id | customer_id | course_id | type | state | course_title | category_title | format | completed_at | transaction_amount | coupon_title | coupon_discount_amount | sale_price | tax_free_amount | pg | method | subcategory_title | marketing_start_at | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 970634.0 | 504760.0 | 201435.0 | ORDER | CANCELLED | 올인원 패키지 : 알고리즘 기술면접 완전 정복 | 프로그래밍 | 올인원 | 2021-03-28 15:00:11 | 90500.0 | NaN | NaN | 110500.0 | 110500.0 | NaN | VBANK | 개발자 커리어 | NaT |
| 1 | 970650.0 | 432862.0 | 203178.0 | ORDER | CANCELLED | 초격차 패키지 : 한번에 끝내는 영상 촬영과 편집 | 영상/3D | 올인원 | 2021-03-28 15:16:53 | 96000.0 | NaN | NaN | 116000.0 | 116000.0 | NaN | CARD | 영상 편집 | 2020-12-02 |
| 2 | 970657.0 | 72297.0 | 204246.0 | PAYMENT | COMPLETED | 시크릿코드 : 프론트엔드 실무 완성편 | 프로그래밍 | 스쿨 온라인 | 2021-03-28 15:21:43 | 171810.0 | [10% 할인] 시크릿코드 실무 완성편 | 19090.0 | 190900.0 | 190900.0 | NaN | CARD | NaN | 2021-03-04 |
| 3 | 970656.0 | 72297.0 | 204246.0 | ORDER | CANCELLED | 시크릿코드 : 프론트엔드 실무 완성편 | 프로그래밍 | 스쿨 온라인 | 2021-03-28 15:21:43 | 171810.0 | NaN | NaN | 190900.0 | 190900.0 | NaN | CARD | NaN | 2021-03-04 |
| 4 | 970658.0 | 478028.0 | 201797.0 | PAYMENT | COMPLETED | 올인원 패키지 : 직장인 필수 스킬 3종 세트 MAX | 업무 생산성 | 올인원 | 2021-03-28 15:21:54 | 97500.0 | [웰컴쿠폰] 올인원 패키지 2만원 할인 쿠폰 | 20000.0 | 117500.0 | 117500.0 | NaN | CARD | PPT/보고서 | 2019-11-14 |
df.info()
<class 'pandas.core.frame.DataFrame'> RangeIndex: 105419 entries, 0 to 105418 Data columns (total 18 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 id 105419 non-null float64 1 customer_id 105416 non-null float64 2 course_id 100212 non-null float64 3 type 105419 non-null object 4 state 105419 non-null object 5 course_title 105403 non-null object 6 category_title 105395 non-null object 7 format 105403 non-null object 8 completed_at 105419 non-null datetime64[ns] 9 transaction_amount 105419 non-null float64 10 coupon_title 31817 non-null object 11 coupon_discount_amount 31817 non-null float64 12 sale_price 104291 non-null float64 13 tax_free_amount 104291 non-null float64 14 pg 90344 non-null object 15 method 92323 non-null object 16 subcategory_title 85590 non-null object 17 marketing_start_at 87440 non-null datetime64[ns] dtypes: datetime64[ns](2), float64(7), object(9) memory usage: 14.5+ MB
# 시각 자료를 이용해 결측치 확인
plt.figure(figsize=(12,5))
sns.heatmap(df.isnull(), cbar=False)
plt.show()
확인 결과
# 결측치 검색
df[df['customer_id'].isnull()]
| id | customer_id | course_id | type | state | course_title | category_title | format | completed_at | transaction_amount | coupon_title | coupon_discount_amount | sale_price | tax_free_amount | pg | method | subcategory_title | marketing_start_at | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 12133 | 1011200.0 | NaN | NaN | TRANSACTION | COMPLETED | NaN | NaN | NaN | 2021-04-12 11:40:00 | 0.0 | NaN | NaN | NaN | NaN | NaN | B2B_CONTRACT | NaN | NaT |
| 36367 | 1066932.0 | NaN | NaN | TRANSACTION | COMPLETED | NaN | NaN | NaN | 2021-05-17 16:12:00 | 0.0 | NaN | NaN | NaN | NaN | NaN | B2B_CONTRACT | NaN | NaT |
| 91500 | 1299115.0 | NaN | NaN | TRANSACTION | COMPLETED | NaN | NaN | NaN | 2021-08-20 20:05:00 | 0.0 | NaN | NaN | NaN | NaN | NaN | B2B_CONTRACT | NaN | NaT |
df = df[df['customer_id'].isnull()==False] # 결측치 제거
df['customer_id'] = df['customer_id'].astype(int) # 정수형 변환
/usr/local/lib/python3.7/dist-packages/ipykernel_launcher.py:2: SettingWithCopyWarning: A value is trying to be set on a copy of a slice from a DataFrame. Try using .loc[row_indexer,col_indexer] = value instead See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy
df[df['course_id'].isnull()].head()
| id | customer_id | course_id | type | state | course_title | category_title | format | completed_at | transaction_amount | coupon_title | coupon_discount_amount | sale_price | tax_free_amount | pg | method | subcategory_title | marketing_start_at | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 6 | 970614.0 | 477910 | NaN | ORDER | CANCELLED | 프로모션 : 2021 내 커리어 지켜 줄 UX/UI 디자인 한끝세트 (3월 프리패스) | 크리에이티브 | 올인원 | 2021-03-28 15:22:36 | 299000.0 | NaN | NaN | 299000.0 | 299000.0 | NaN | CARD | NaN | NaT |
| 12 | 970670.0 | 429291 | NaN | ORDER | CANCELLED | 프로모션 : 코딩 LEVEL UP 웹 개발 풀스텍 한끝세트 (3월 프리패스) | 프로그래밍 | 올인원 | 2021-03-28 15:27:29 | 299000.0 | NaN | NaN | 299000.0 | 299000.0 | NaN | CARD | NaN | NaT |
| 13 | 970672.0 | 429291 | NaN | ORDER | CANCELLED | 프로모션 : 코딩 LEVEL UP 웹 개발 풀스텍 한끝세트 (3월 프리패스) | 프로그래밍 | 올인원 | 2021-03-28 15:30:05 | 299000.0 | NaN | NaN | 299000.0 | 299000.0 | NaN | CARD | NaN | NaT |
| 16 | 970677.0 | 429291 | NaN | ORDER | CANCELLED | 프로모션 : 코딩 LEVEL UP 웹 개발 풀스텍 한끝세트 (3월 프리패스) | 프로그래밍 | 올인원 | 2021-03-28 15:31:29 | 299000.0 | NaN | NaN | 299000.0 | 299000.0 | NaN | CARD | NaN | NaT |
| 18 | 970682.0 | 478031 | NaN | PAYMENT | COMPLETED | 프로모션 : 기초부터 시작하는 데이터분석 한끝세트 (3월 프리패스) | 데이터사이언스 | 올인원 | 2021-03-28 15:33:28 | 299000.0 | NaN | NaN | 299000.0 | 299000.0 | NaN | CARD | NaN | NaT |
# 일부 값 빼고 전부 deleted
df[df['course_title'].isnull()]
| id | customer_id | course_id | type | state | course_title | category_title | format | completed_at | transaction_amount | coupon_title | coupon_discount_amount | sale_price | tax_free_amount | pg | method | subcategory_title | marketing_start_at | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 9002 | 996843.0 | 490139 | NaN | PAYMENT | DELETED | NaN | NaN | NaN | 2021-04-07 15:05:06 | 480000.0 | NaN | NaN | NaN | NaN | NaN | TRANSFER | NaN | NaT |
| 9003 | 996793.0 | 490089 | NaN | PAYMENT | DELETED | NaN | NaN | NaN | 2021-04-07 15:05:06 | 600000.0 | NaN | NaN | NaN | NaN | NaN | TRANSFER | NaN | NaT |
| 9004 | 996842.0 | 490138 | NaN | PAYMENT | DELETED | NaN | NaN | NaN | 2021-04-07 15:05:06 | 600000.0 | NaN | NaN | NaN | NaN | NaN | TRANSFER | NaN | NaT |
| 9005 | 996851.0 | 490149 | NaN | PAYMENT | DELETED | NaN | NaN | NaN | 2021-04-07 15:05:06 | 600000.0 | NaN | NaN | NaN | NaN | NaN | TRANSFER | NaN | NaT |
| 12181 | 1006736.0 | 291328 | NaN | PAYMENT | DELETED | NaN | NaN | NaN | 2021-04-12 13:10:10 | 967000.0 | NaN | NaN | NaN | NaN | NaN | TRANSFER | NaN | NaT |
| 13754 | 1012747.0 | 498414 | NaN | PAYMENT | DELETED | NaN | NaN | NaN | 2021-04-15 20:40:35 | 170000.0 | NaN | NaN | NaN | NaN | NaN | TRANSFER | NaN | NaT |
| 31192 | 1063323.0 | 524510 | NaN | PAYMENT | DELETED | NaN | NaN | NaN | 2021-05-10 18:04:33 | 35000.0 | NaN | NaN | NaN | NaN | NaN | TRANSFER | NaN | NaT |
| 38944 | 1093777.0 | 539708 | NaN | PAYMENT | DELETED | NaN | NaN | NaN | 2021-05-22 10:57:39 | 127500.0 | NaN | NaN | NaN | NaN | NaN | TRANSFER | NaN | NaT |
| 40377 | 1093780.0 | 539709 | NaN | PAYMENT | DELETED | NaN | NaN | NaN | 2021-05-24 09:18:48 | 110000.0 | NaN | NaN | NaN | NaN | NaN | TRANSFER | NaN | NaT |
| 40378 | 1093784.0 | 539709 | NaN | PAYMENT | DELETED | NaN | NaN | NaN | 2021-05-24 09:18:48 | 110000.0 | NaN | NaN | NaN | NaN | NaN | TRANSFER | NaN | NaT |
| 47361 | 1117129.0 | 549990 | NaN | PAYMENT | COMPLETED | NaN | NaN | NaN | 2021-06-02 16:48:37 | 10500000.0 | NaN | NaN | NaN | NaN | NaN | TRANSFER | NaN | NaT |
| 53960 | 1141801.0 | 560947 | NaN | PAYMENT | DELETED | NaN | NaN | NaN | 2021-06-13 19:13:41 | 172000.0 | NaN | NaN | NaN | NaN | NaN | TRANSFER | NaN | NaT |
| 56316 | 1155478.0 | 567600 | NaN | PAYMENT | DELETED | NaN | NaN | NaN | 2021-06-18 01:38:26 | 1200000.0 | NaN | NaN | NaN | NaN | NaN | ONSITE | NaN | NaT |
# Payment-Completed 건이 있으나 문의 결과 제거해도 무관하다 하여 제거
df = df.dropna(subset=['course_title'])
2-1. 테스트용, TEST, 샘플 제거
# 해당 조건에 맞는 값 추출
t = df[df["course_title"].str.contains("TEST") | df["course_title"].str.contains("테스트용") | df['course_title'].str.contains("샘플")]
t
| id | customer_id | course_id | type | state | course_title | category_title | format | completed_at | transaction_amount | coupon_title | coupon_discount_amount | sale_price | tax_free_amount | pg | method | subcategory_title | marketing_start_at | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 20875 | 1034021.0 | 49600 | 205142.0 | PAYMENT | COMPLETED | 스프링 아카데미아 15개 영상강의 코스(5월) - 샘플 강의 제공용 | 프로그래밍 | 스쿨 온라인 | 2021-04-27 19:03:10 | 0.0 | NaN | NaN | 1.0 | 1.0 | NaN | PROMOTION | NaN | NaT |
| 20899 | 1034100.0 | 270040 | 205142.0 | PAYMENT | COMPLETED | 스프링 아카데미아 15개 영상강의 코스(5월) - 샘플 강의 제공용 | 프로그래밍 | 스쿨 온라인 | 2021-04-27 19:50:54 | 0.0 | NaN | NaN | 1.0 | 1.0 | NaN | PROMOTION | NaN | NaT |
| 20900 | 1034101.0 | 470930 | 205142.0 | PAYMENT | COMPLETED | 스프링 아카데미아 15개 영상강의 코스(5월) - 샘플 강의 제공용 | 프로그래밍 | 스쿨 온라인 | 2021-04-27 19:50:57 | 0.0 | NaN | NaN | 1.0 | 1.0 | NaN | PROMOTION | NaN | NaT |
| 20901 | 1034102.0 | 33271 | 205142.0 | PAYMENT | COMPLETED | 스프링 아카데미아 15개 영상강의 코스(5월) - 샘플 강의 제공용 | 프로그래밍 | 스쿨 온라인 | 2021-04-27 19:51:05 | 0.0 | NaN | NaN | 1.0 | 1.0 | NaN | PROMOTION | NaN | NaT |
| 20902 | 1034104.0 | 144798 | 205142.0 | PAYMENT | COMPLETED | 스프링 아카데미아 15개 영상강의 코스(5월) - 샘플 강의 제공용 | 프로그래밍 | 스쿨 온라인 | 2021-04-27 19:51:24 | 0.0 | NaN | NaN | 1.0 | 1.0 | NaN | PROMOTION | NaN | NaT |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 51406 | 1129889.0 | 496508 | NaN | ORDER | CANCELLED | (테스트용) 프로모션 : 기초부터 시작하는 데이터분석 프리패스 (5월 삼성 패키지 ... | 데이터사이언스 | 올인원 | 2021-06-09 15:51:44 | 990000.0 | NaN | NaN | 990000.0 | 176000.0 | NAVER | NaN | NaN | NaT |
| 51435 | 1129971.0 | 496508 | NaN | PAYMENT | COMPLETED | (테스트용) 프로모션 : 기초부터 시작하는 데이터분석 프리패스 (5월 삼성 패키지 ... | 데이터사이언스 | 올인원 | 2021-06-09 16:32:25 | 990000.0 | NaN | NaN | 990000.0 | 176000.0 | NAVER | CARD | NaN | NaT |
| 51782 | 1131318.0 | 496508 | NaN | REFUND | COMPLETED | (테스트용) 프로모션 : 기초부터 시작하는 데이터분석 프리패스 (5월 삼성 패키지 ... | 데이터사이언스 | 올인원 | 2021-06-10 11:20:35 | -990000.0 | NaN | NaN | 990000.0 | 176000.0 | NAVER | CARD | NaN | NaT |
| 56001 | 1146954.0 | 496508 | NaN | ORDER | CANCELLED | (테스트용) 프로모션 : 기초부터 시작하는 데이터분석 프리패스 (5월 삼성 패키지 ... | 데이터사이언스 | 올인원 | 2021-06-17 13:50:43 | 990000.0 | NaN | NaN | 990000.0 | 176000.0 | NAVER | NaN | NaN | NaT |
| 56137 | 1147445.0 | 496508 | NaN | ORDER | CANCELLED | (테스트용) 프로모션 : 기초부터 시작하는 데이터분석 프리패스 (5월 삼성 패키지 ... | 데이터사이언스 | 올인원 | 2021-06-17 17:20:09 | 990000.0 | NaN | NaN | 990000.0 | 176000.0 | NAVER | NaN | NaN | NaT |
252 rows × 18 columns
# 추려낸 이상치 값 전부 drop
df = df.drop(list(t.index))
2-2. 'A/B테스트', '코딩테스트' 제외한 '테스트' 항목 추가 제거
# 해당 단어가 포함된 course_id 검색
df[df["course_title"].str.contains("테스트")]["course_title"].unique()
array(['초격차 패키지 : 한 번에 끝내는 코딩테스트 369 Java편',
'네카라쿠배 프론트엔드 취업완성 스쿨 2기_1차 테스트',
'올인원 패키지 : A/B 테스트 탑재, 개인화 마케팅 끝장내기',
'프로모션 : 2+2 코딩테스트 결과를 바꾸는 전공생 코딩 PASS (6월 프리패스)',
'네카라쿠배 프론트엔드 취업완성 스쿨 2기_2차 테스트', '(B2B) 경남대학교_코딩 테스트 대비반',
'프로모션 : 코딩테스트 결과를 바꾸는 전공생 코딩 BEST PASS (7월 프리패스)',
'(초격차변경)프로모션 : 코딩테스트 결과를 바꾸는 전공생 코딩 BEST PASS (7월 프리패스)',
'프로모션 : 코딩테스트 결과를 바꾸는 전공생 코딩 iPad 패키지 (7월 현물 프리패스)',
'The RED : 고객 경험을 개선하는 A/B테스트 기반 모바일 앱 개발 by 이승민'], dtype=object)
# 해당 강의의 transaction_amount 0원, sale_price는 1원이라 이상치라 판단, drop
df[df["course_title"].str.contains("네카라쿠배 프론트엔드 취업완성 스쿨")]
| id | customer_id | course_id | type | state | course_title | category_title | format | completed_at | transaction_amount | coupon_title | coupon_discount_amount | sale_price | tax_free_amount | pg | method | subcategory_title | marketing_start_at | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 30770 | 1062130.0 | 523886 | 205237.0 | PAYMENT | COMPLETED | 네카라쿠배 프론트엔드 취업완성 스쿨 2기_1차 테스트 | 프로그래밍 | 스쿨 | 2021-05-10 10:58:57 | 0.0 | NaN | NaN | 1.0 | 1.0 | NaN | PROMOTION | NaN | 2019-04-19 |
| 30783 | 1062160.0 | 84972 | 205237.0 | PAYMENT | COMPLETED | 네카라쿠배 프론트엔드 취업완성 스쿨 2기_1차 테스트 | 프로그래밍 | 스쿨 | 2021-05-10 11:11:21 | 0.0 | NaN | NaN | 1.0 | 1.0 | NaN | PROMOTION | NaN | 2019-04-19 |
| 30814 | 1062222.0 | 513608 | 205237.0 | PAYMENT | COMPLETED | 네카라쿠배 프론트엔드 취업완성 스쿨 2기_1차 테스트 | 프로그래밍 | 스쿨 | 2021-05-10 11:39:56 | 0.0 | NaN | NaN | 1.0 | 1.0 | NaN | PROMOTION | NaN | 2019-04-19 |
| 30822 | 1062238.0 | 438870 | 205237.0 | PAYMENT | COMPLETED | 네카라쿠배 프론트엔드 취업완성 스쿨 2기_1차 테스트 | 프로그래밍 | 스쿨 | 2021-05-10 11:50:03 | 0.0 | NaN | NaN | 1.0 | 1.0 | NaN | PROMOTION | NaN | 2019-04-19 |
| 30824 | 1062248.0 | 523942 | 205237.0 | PAYMENT | COMPLETED | 네카라쿠배 프론트엔드 취업완성 스쿨 2기_1차 테스트 | 프로그래밍 | 스쿨 | 2021-05-10 11:55:30 | 0.0 | NaN | NaN | 1.0 | 1.0 | NaN | PROMOTION | NaN | 2019-04-19 |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 54402 | 1141156.0 | 546174 | 205715.0 | PAYMENT | COMPLETED | 네카라쿠배 프론트엔드 취업완성 스쿨 2기_2차 테스트 | 프로그래밍 | 스쿨 | 2021-06-14 12:34:02 | 0.0 | NaN | NaN | 1.0 | 1.0 | NaN | PROMOTION | NaN | 2021-02-08 |
| 54447 | 1141335.0 | 67113 | 205715.0 | PAYMENT | COMPLETED | 네카라쿠배 프론트엔드 취업완성 스쿨 2기_2차 테스트 | 프로그래밍 | 스쿨 | 2021-06-14 14:25:11 | 0.0 | NaN | NaN | 1.0 | 1.0 | NaN | PROMOTION | NaN | 2021-02-08 |
| 54491 | 1141485.0 | 523266 | 205715.0 | PAYMENT | COMPLETED | 네카라쿠배 프론트엔드 취업완성 스쿨 2기_2차 테스트 | 프로그래밍 | 스쿨 | 2021-06-14 15:46:16 | 0.0 | NaN | NaN | 1.0 | 1.0 | NaN | PROMOTION | NaN | 2021-02-08 |
| 54611 | 1141900.0 | 560997 | 205237.0 | PAYMENT | COMPLETED | 네카라쿠배 프론트엔드 취업완성 스쿨 2기_1차 테스트 | 프로그래밍 | 스쿨 | 2021-06-14 19:25:34 | 0.0 | NaN | NaN | 1.0 | 1.0 | NaN | PROMOTION | NaN | 2019-04-19 |
| 54755 | 1142513.0 | 524458 | 205237.0 | PAYMENT | COMPLETED | 네카라쿠배 프론트엔드 취업완성 스쿨 2기_1차 테스트 | 프로그래밍 | 스쿨 | 2021-06-15 00:11:03 | 0.0 | NaN | NaN | 1.0 | 1.0 | NaN | PROMOTION | NaN | 2019-04-19 |
947 rows × 18 columns
# 해당 강의들을 제외한 '테스트' 포함된 row 추려내기
t = df[~(df["course_title"].str.contains("A/B테스트"))&~(df["course_title"].str.contains("A/B 테스트"))&~(df["course_title"].str.contains("코딩 테스트"))&~(df["course_title"].str.contains("코딩테스트"))&df["course_title"].str.contains("테스트")]
# 추려낸 이상치 drop
df = df.drop(list(t.index))
df[df['category_title'].isnull()]
| id | customer_id | course_id | type | state | course_title | category_title | format | completed_at | transaction_amount | coupon_title | coupon_discount_amount | sale_price | tax_free_amount | pg | method | subcategory_title | marketing_start_at | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 41878 | 1078156.0 | 62566 | NaN | REFUND | COMPLETED | 프로모션 : 자유이용권 (3월) | NaN | 온라인 | 2021-05-26 22:06:00 | -199000.0 | NaN | NaN | 199000.0 | 199000.0 | NaN | TRANSFER | NaN | NaT |
| 72639 | 1212937.0 | 591404 | NaN | PAYMENT | COMPLETED | 프로모션 : 풀스택 데이터 사이언티스트를 위한 필수 iPad 패키지 (7월 현물 프... | NaN | 올인원 | 2021-07-12 23:38:42 | 990000.0 | NaN | NaN | 990000.0 | 272800.0 | INICIS | CARD | NaN | NaT |
| 74973 | 1223470.0 | 598011 | NaN | ORDER | CANCELLED | 프로모션 : 풀스택 데이터 사이언티스트를 위한 필수 iPad 패키지 (7월 현물 프... | NaN | 올인원 | 2021-07-18 12:26:46 | 990000.0 | NaN | NaN | 990000.0 | 272800.0 | INICIS | CARD | NaN | NaT |
| 74975 | 1223480.0 | 598011 | NaN | PAYMENT | COMPLETED | 프로모션 : 풀스택 데이터 사이언티스트를 위한 필수 iPad 패키지 (7월 현물 프... | NaN | 올인원 | 2021-07-18 12:31:01 | 990000.0 | NaN | NaN | 990000.0 | 272800.0 | INICIS | CARD | NaN | NaT |
| 74980 | 1223479.0 | 598011 | NaN | ORDER | COMPLETED | 프로모션 : 풀스택 데이터 사이언티스트를 위한 필수 iPad 패키지 (7월 현물 프... | NaN | 올인원 | 2021-07-18 12:40:08 | 990000.0 | NaN | NaN | 990000.0 | 272800.0 | INICIS | CARD | NaN | NaT |
| 104056 | 1356347.0 | 561379 | NaN | PAYMENT | CANCELLED | 프로모션 : 영상편집 맥북 pro 패스(9월 현물 프리패스) | NaN | 올인원 | 2021-09-20 18:15:02 | 1800000.0 | NaN | NaN | 1800000.0 | 295200.0 | INICIS | CARD | NaN | NaT |
| 104318 | 1358067.0 | 617692 | NaN | PAYMENT | CANCELLED | 프로모션 : 영상편집 맥북 pro 패스(9월 현물 프리패스) | NaN | 올인원 | 2021-09-22 00:57:03 | 1800000.0 | NaN | NaN | 1800000.0 | 295200.0 | NAVER | NaN | NaN | NaT |
| 105189 | 1363817.0 | 83845 | NaN | PAYMENT | CANCELLED | 프로모션 : 영상편집 맥북 pro 패스(9월 현물 프리패스) | NaN | 올인원 | 2021-09-24 15:36:27 | 1800000.0 | NaN | NaN | 1800000.0 | 295200.0 | INICIS | CARD | NaN | NaT |
# 인덱스(72639, 74945) 으로 접근
df.loc[72639, "category_title"] = "데이터사이언스"
df.loc[74975, "category_title"] = "데이터사이언스"
df = df.dropna(subset=["category_title"])
'데이터 사이언스' 공백 문자 제거 필요
def func(x):
return x.replace(" ", "")
df['category_title'] = df['category_title'].apply(func)
/usr/local/lib/python3.7/dist-packages/ipykernel_launcher.py:4: SettingWithCopyWarning: A value is trying to be set on a copy of a slice from a DataFrame. Try using .loc[row_indexer,col_indexer] = value instead See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy after removing the cwd from sys.path.
df['category_title'].value_counts() # .nunique()
프로그래밍 33238 데이터사이언스 14082 업무생산성 13323 디자인 12009 영상/3D 10260 마케팅 9857 부동산/금융 5523 투자/재테크 2501 크리에이티브 2250 교육 1031 지식콘텐츠 56 비즈니스 42 파이낸스 25 일러스트 1 Name: category_title, dtype: int64
df[df['subcategory_title'].isnull()].head()
| id | customer_id | course_id | type | state | course_title | category_title | format | completed_at | transaction_amount | coupon_title | coupon_discount_amount | sale_price | tax_free_amount | pg | method | subcategory_title | marketing_start_at | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 2 | 970657.0 | 72297 | 204246.0 | PAYMENT | COMPLETED | 시크릿코드 : 프론트엔드 실무 완성편 | 프로그래밍 | 스쿨 온라인 | 2021-03-28 15:21:43 | 171810.0 | [10% 할인] 시크릿코드 실무 완성편 | 19090.0 | 190900.0 | 190900.0 | NaN | CARD | NaN | 2021-03-04 |
| 3 | 970656.0 | 72297 | 204246.0 | ORDER | CANCELLED | 시크릿코드 : 프론트엔드 실무 완성편 | 프로그래밍 | 스쿨 온라인 | 2021-03-28 15:21:43 | 171810.0 | NaN | NaN | 190900.0 | 190900.0 | NaN | CARD | NaN | 2021-03-04 |
| 6 | 970614.0 | 477910 | NaN | ORDER | CANCELLED | 프로모션 : 2021 내 커리어 지켜 줄 UX/UI 디자인 한끝세트 (3월 프리패스) | 크리에이티브 | 올인원 | 2021-03-28 15:22:36 | 299000.0 | NaN | NaN | 299000.0 | 299000.0 | NaN | CARD | NaN | NaT |
| 10 | 970671.0 | 469860 | 203644.0 | PAYMENT | COMPLETED | 올인원 패키지 : 권오상의 금융 아카데미 - 권오상의 재무제표 분석 기초(평생소장) | 부동산/금융 | 올인원 | 2021-03-28 15:27:17 | 263000.0 | NaN | NaN | 263000.0 | 263000.0 | NaN | CARD | NaN | 2020-11-27 |
| 11 | 970668.0 | 469860 | 203644.0 | ORDER | CANCELLED | 올인원 패키지 : 권오상의 금융 아카데미 - 권오상의 재무제표 분석 기초(평생소장) | 부동산/금융 | 올인원 | 2021-03-28 15:27:17 | 263000.0 | NaN | NaN | 263000.0 | 263000.0 | NaN | CARD | NaN | 2020-11-27 |
df.loc[df['subcategory_title'].isnull(),"subcategory_title"] = df.loc[df['subcategory_title'].isnull(),"category_title"]
df['purchased'] = (df['type'] == 'PAYMENT') & (df['state'] == 'COMPLETED')
pt = df[(df['type']=='PAYMENT')&(df['state']=='COMPLETED')] # 구매 데이터
rt = df[(df['type']=='REFUND')&(df['state']=='COMPLETED')] # 환불 데이터
paid = list(zip(pt['customer_id'].astype(float), pt['course_id'].astype(float)))
ref = list(zip(rt['customer_id'].astype(float), rt['course_id'].astype(float), rt['id']))
# 중요!
# [customer_id],[course_id]가 일치하는 값 = 환불 후 재구매하지 않은 케이스
# 이 외의 다른 케이스는 쿠폰 등을 사용하여 재결제 했을 가능성 있음 -> 순수 환불이 아님
# 'payment-completed'와 'refund-completed'의 [customer_id],[course_id] 비교
# 결과 값을 real_ref에 담아둔다
real_ref = []
for i in range(len(paid)):
for j in range(len(ref)):
if paid[i][0] == ref[j][0] and paid[i][1] == ref[j][1]:
real_ref.append(ref[j])
ref.remove(ref[j])
break
print(len(paid),len(real_ref),len(ref))
51707 1927 1893
payment-completed 의 refund-completed (순수 환불) 환불데이터만 따로 분리
# real_refund (순수 환불 건수) Data 확인
t = np.array(real_ref)
rt = rt[rt['id'].isin(t[:,2])]
rt
| id | customer_id | course_id | type | state | course_title | category_title | format | completed_at | transaction_amount | coupon_title | coupon_discount_amount | sale_price | tax_free_amount | pg | method | subcategory_title | marketing_start_at | purchased | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 759 | 972662.0 | 271507 | 204246.0 | REFUND | COMPLETED | 시크릿코드 : 프론트엔드 실무 완성편 | 프로그래밍 | 스쿨 온라인 | 2021-03-29 10:28:46 | -171810.0 | NaN | NaN | 190900.0 | 190900.0 | NaN | CARD | 프로그래밍 | 2021-03-04 00:00:00 | False |
| 1165 | 973680.0 | 498409 | 203782.0 | REFUND | COMPLETED | 초격차 패키지 : 한번에 끝내는 모션그래픽 | 영상/3D | 올인원 | 2021-03-29 14:39:49 | -139000.0 | NaN | NaN | 139000.0 | 139000.0 | NaN | CARD | 모션그래픽 | 2021-01-22 00:00:00 | False |
| 1170 | 973686.0 | 462160 | 203328.0 | REFUND | COMPLETED | 올인원 패키지 : 디자이너 몰래 듣는 압축 포토샵 | 디자인 | 올인원 | 2021-03-29 14:41:27 | -77600.0 | NaN | NaN | 87600.0 | 87600.0 | NaN | CARD | 디자인툴 | 2020-10-23 00:00:00 | False |
| 1198 | 973764.0 | 474332 | 203720.0 | REFUND | COMPLETED | 초격차 패키지 : 한 번에 끝내는 프론트엔드 개발 | 프로그래밍 | 올인원 | 2021-03-29 14:58:53 | -111000.0 | NaN | NaN | 111000.0 | 111000.0 | NaN | CARD | 프론트엔드 개발 | 2021-02-02 00:00:00 | False |
| 1367 | 974226.0 | 475655 | 204037.0 | REFUND | COMPLETED | 매주)서비스 기획서 완성 온라인 완주반 2101 | 크리에이티브 | 온라인 완주반 | 2021-03-29 17:23:15 | -367000.0 | NaN | NaN | 417000.0 | 417000.0 | NaN | CARD | 크리에이티브 | 2021-01-14 00:00:00 | False |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 105133 | 1363558.0 | 656066 | 205761.0 | REFUND | COMPLETED | 초격차 패키지 : 한 번에 끝내는 디지털 마케팅 | 마케팅 | 올인원 | 2021-09-24 13:33:08 | -213000.0 | NaN | NaN | 233000.0 | 233000.0 | INICIS | CARD | 디지털마케팅 | 2021-08-17 00:00:00 | False |
| 105139 | 1363576.0 | 648937 | 204013.0 | REFUND | COMPLETED | 올인원 패키지 : 완전정복 시각디자인 기초 | 디자인 | 올인원 | 2021-09-24 13:43:57 | -72000.0 | NaN | NaN | 174000.0 | 174000.0 | NAVER | CARD | 시각디자인 | 2021-03-16 00:00:00 | False |
| 105168 | 1363704.0 | 670215 | 204670.0 | REFUND | COMPLETED | The RED : 김영하 작가의 내 안의 숨은 이야기를 찾아 쓰는 법 | 마케팅 | RED | 2021-09-24 14:32:43 | -171000.0 | NaN | NaN | 171000.0 | 171000.0 | NAVER | TRANS | 글쓰기/카피라이팅 | 2021-06-18 17:00:00 | False |
| 105245 | 1364149.0 | 604077 | 205569.0 | REFUND | COMPLETED | 올인원 패키지 : 공여사와 무작정 풀어보는 엑셀 실무 | 업무생산성 | 올인원 | 2021-09-24 17:09:30 | -109000.0 | NaN | NaN | 129000.0 | 129000.0 | KAKAO | POINT | 엑셀/VBA | 2021-08-17 00:00:00 | False |
| 105248 | 1364217.0 | 552100 | 203525.0 | REFUND | COMPLETED | 초격차 패키지 : 한번에 끝내는 Java/Spring 웹 개발 마스터 | 프로그래밍 | 올인원 | 2021-09-24 17:33:53 | -108186.0 | NaN | NaN | 114000.0 | 114000.0 | INICIS | CARD | 백엔드 개발 | 2021-02-01 00:00:00 | False |
1927 rows × 19 columns
51707-1927
49780
payment-completed 테이블에서 이와 짝이 맞는 refund 값을 빼주면 49816이 나와야 한다
for i in range(len(df)):
a = float(df.iloc[i,1]) # = customer_id
b = float(df.iloc[i,2]) # = course_id
if df.iloc[i,18] == True: # = purchased = True인 값
for j in range(len(real_ref)): # 값 비교
if real_ref[j][0] == a and real_ref[j][1] == b: # 환불 리스트에 해당 customer_id, course_id 있을 경우
df.iloc[i,18] = False # True에서 False로 변경
real_ref.remove(real_ref[j]) # 중복 방지를 위해 해당 값 삭제
break
df['purchased'].value_counts()
False 54418 True 49780 Name: purchased, dtype: int64
# 순 구매 건 확인
pt = df[df['purchased'] == True]
pt
| id | customer_id | course_id | type | state | course_title | category_title | format | completed_at | transaction_amount | coupon_title | coupon_discount_amount | sale_price | tax_free_amount | pg | method | subcategory_title | marketing_start_at | purchased | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 2 | 970657.0 | 72297 | 204246.0 | PAYMENT | COMPLETED | 시크릿코드 : 프론트엔드 실무 완성편 | 프로그래밍 | 스쿨 온라인 | 2021-03-28 15:21:43 | 171810.0 | [10% 할인] 시크릿코드 실무 완성편 | 19090.0 | 190900.0 | 190900.0 | NaN | CARD | 프로그래밍 | 2021-03-04 | True |
| 4 | 970658.0 | 478028 | 201797.0 | PAYMENT | COMPLETED | 올인원 패키지 : 직장인 필수 스킬 3종 세트 MAX | 업무생산성 | 올인원 | 2021-03-28 15:21:54 | 97500.0 | [웰컴쿠폰] 올인원 패키지 2만원 할인 쿠폰 | 20000.0 | 117500.0 | 117500.0 | NaN | CARD | PPT/보고서 | 2019-11-14 | True |
| 8 | 970669.0 | 478033 | 203178.0 | PAYMENT | COMPLETED | 초격차 패키지 : 한번에 끝내는 영상 촬영과 편집 | 영상/3D | 올인원 | 2021-03-28 15:26:47 | 96000.0 | [웰컴쿠폰] 올인원 패키지 2만원 할인 쿠폰 | 20000.0 | 116000.0 | 116000.0 | NaN | CARD | 영상 편집 | 2020-12-02 | True |
| 10 | 970671.0 | 469860 | 203644.0 | PAYMENT | COMPLETED | 올인원 패키지 : 권오상의 금융 아카데미 - 권오상의 재무제표 분석 기초(평생소장) | 부동산/금융 | 올인원 | 2021-03-28 15:27:17 | 263000.0 | NaN | NaN | 263000.0 | 263000.0 | NaN | CARD | 부동산/금융 | 2020-11-27 | True |
| 18 | 970682.0 | 478031 | NaN | PAYMENT | COMPLETED | 프로모션 : 기초부터 시작하는 데이터분석 한끝세트 (3월 프리패스) | 데이터사이언스 | 올인원 | 2021-03-28 15:33:28 | 299000.0 | NaN | NaN | 299000.0 | 299000.0 | NaN | CARD | 데이터사이언스 | NaT | True |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 105411 | 1364969.0 | 669238 | 204286.0 | PAYMENT | COMPLETED | 초격차 패키지 : 한번에 끝내는 3D 디자인 툴 | 디자인 | 올인원 | 2021-09-25 13:39:26 | 212000.0 | [미래투자금] 온라인 강의 2만원 할인쿠폰 | 20000.0 | 232000.0 | 232000.0 | INICIS | CARD | 디자인툴 | 2021-04-23 | True |
| 105412 | 1364976.0 | 384003 | 203178.0 | PAYMENT | COMPLETED | 초격차 패키지 : 한번에 끝내는 영상 촬영과 편집 | 영상/3D | 올인원 | 2021-09-25 13:46:29 | 149000.0 | NaN | NaN | 149000.0 | 149000.0 | KAKAO | CARD | 영상 편집 | 2020-12-02 | True |
| 105413 | 1364991.0 | 670891 | 203935.0 | PAYMENT | COMPLETED | 초격차 패키지 : 한 번에 끝내는 파이썬 웹 개발 | 프로그래밍 | 올인원 | 2021-09-25 14:01:26 | 159000.0 | [미래투자금] 온라인 강의 2만원 할인쿠폰 | 20000.0 | 179000.0 | 179000.0 | INICIS | CARD | 백엔드 개발 | 2021-05-31 | True |
| 105416 | 1364996.0 | 640697 | 205365.0 | PAYMENT | COMPLETED | 초격차 패키지 : 한 번에 끝내는 유튜브 크리에이터 되기 | 영상/3D | 올인원 | 2021-09-25 14:17:41 | 96000.0 | [WELCOME] 온라인 강의 2만원 할인쿠폰 | 20000.0 | 116000.0 | 116000.0 | INICIS | VBANK | 영상 편집 | 2021-06-15 | True |
| 105418 | 1365007.0 | 610626 | 206720.0 | PAYMENT | COMPLETED | 용호수의 돈 버는 실전 영상 제작 | 영상/3D | 올인원 | 2021-09-25 14:25:47 | 139000.0 | [WELCOME] 온라인 강의 3만원 할인쿠폰 | 30000.0 | 169000.0 | 169000.0 | NAVER | POINT | 영상 편집 | 2021-08-17 | True |
49780 rows × 19 columns
pt.info()
<class 'pandas.core.frame.DataFrame'> Int64Index: 49780 entries, 2 to 105418 Data columns (total 19 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 id 49780 non-null float64 1 customer_id 49780 non-null int64 2 course_id 47802 non-null float64 3 type 49780 non-null object 4 state 49780 non-null object 5 course_title 49780 non-null object 6 category_title 49780 non-null object 7 format 49780 non-null object 8 completed_at 49780 non-null datetime64[ns] 9 transaction_amount 49780 non-null float64 10 coupon_title 22928 non-null object 11 coupon_discount_amount 22928 non-null float64 12 sale_price 48715 non-null float64 13 tax_free_amount 48715 non-null float64 14 pg 41300 non-null object 15 method 49780 non-null object 16 subcategory_title 49780 non-null object 17 marketing_start_at 40960 non-null datetime64[ns] 18 purchased 49780 non-null bool dtypes: bool(1), datetime64[ns](2), float64(6), int64(1), object(9) memory usage: 7.3+ MB
# taxfreeamount와 saleprice 가 다른 강좌들은 모두 쿠폰이 없음
pt[(pt["sale_price"]!= pt["tax_free_amount"]) & (~pt["coupon_title"].isnull())]
| id | customer_id | course_id | type | state | course_title | category_title | format | completed_at | transaction_amount | coupon_title | coupon_discount_amount | sale_price | tax_free_amount | pg | method | subcategory_title | marketing_start_at | purchased | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 90776 | 1294906.0 | 636868 | 207018.0 | PAYMENT | COMPLETED | K-Digital Credit 빅데이터 분석 첫걸음 시작하기_1기(평생소장용) | 프로그래밍 | B2G | 2021-08-18 17:06:15 | 0.0 | K-Digital Credit 빅데이터분석 첫걸음 시작하기_1기(평생소장용) | 300000.0 | 300000.0 | 0.0 | NaN | PROMOTION | 프로그래밍 | NaT | True |
| 91173 | 1297293.0 | 576889 | 207018.0 | PAYMENT | COMPLETED | K-Digital Credit 빅데이터 분석 첫걸음 시작하기_1기(평생소장용) | 프로그래밍 | B2G | 2021-08-19 21:18:31 | 0.0 | K-Digital Credit 빅데이터분석 첫걸음 시작하기_1기(평생소장용) | 300000.0 | 300000.0 | 0.0 | NaN | PROMOTION | 프로그래밍 | NaT | True |
| 91235 | 1297690.0 | 551722 | 207018.0 | PAYMENT | COMPLETED | K-Digital Credit 빅데이터 분석 첫걸음 시작하기_1기(평생소장용) | 프로그래밍 | B2G | 2021-08-20 00:58:38 | 0.0 | K-Digital Credit 빅데이터분석 첫걸음 시작하기_1기(평생소장용) | 300000.0 | 300000.0 | 0.0 | NaN | PROMOTION | 프로그래밍 | NaT | True |
| 91340 | 1298260.0 | 465057 | 207018.0 | PAYMENT | COMPLETED | K-Digital Credit 빅데이터 분석 첫걸음 시작하기_1기(평생소장용) | 프로그래밍 | B2G | 2021-08-20 13:31:48 | 0.0 | K-Digital Credit 빅데이터분석 첫걸음 시작하기_1기(평생소장용) | 300000.0 | 300000.0 | 0.0 | NaN | PROMOTION | 프로그래밍 | NaT | True |
| 91450 | 1298849.0 | 43421 | 207018.0 | PAYMENT | COMPLETED | K-Digital Credit 빅데이터 분석 첫걸음 시작하기_1기(평생소장용) | 프로그래밍 | B2G | 2021-08-20 17:38:33 | 0.0 | K-Digital Credit 빅데이터분석 첫걸음 시작하기_1기(평생소장용) | 300000.0 | 300000.0 | 0.0 | NaN | PROMOTION | 프로그래밍 | NaT | True |
| 91648 | 1299763.0 | 567768 | 207018.0 | PAYMENT | COMPLETED | K-Digital Credit 빅데이터 분석 첫걸음 시작하기_1기(평생소장용) | 프로그래밍 | B2G | 2021-08-21 12:55:36 | 0.0 | K-Digital Credit 빅데이터분석 첫걸음 시작하기_1기(평생소장용) | 300000.0 | 300000.0 | 0.0 | NaN | PROMOTION | 프로그래밍 | NaT | True |
| 91657 | 1299787.0 | 145454 | 207018.0 | PAYMENT | COMPLETED | K-Digital Credit 빅데이터 분석 첫걸음 시작하기_1기(평생소장용) | 프로그래밍 | B2G | 2021-08-21 13:31:01 | 0.0 | K-Digital Credit 빅데이터분석 첫걸음 시작하기_1기(평생소장용) | 300000.0 | 300000.0 | 0.0 | NaN | PROMOTION | 프로그래밍 | NaT | True |
| 91773 | 1300260.0 | 558182 | 207018.0 | PAYMENT | COMPLETED | K-Digital Credit 빅데이터 분석 첫걸음 시작하기_1기(평생소장용) | 프로그래밍 | B2G | 2021-08-21 21:25:46 | 0.0 | K-Digital Credit 빅데이터분석 첫걸음 시작하기_1기(평생소장용) | 300000.0 | 300000.0 | 0.0 | NaN | PROMOTION | 프로그래밍 | NaT | True |
| 92616 | 1303890.0 | 559793 | 207018.0 | PAYMENT | COMPLETED | K-Digital Credit 빅데이터 분석 첫걸음 시작하기_1기(평생소장용) | 프로그래밍 | B2G | 2021-08-24 09:41:40 | 0.0 | K-Digital Credit 빅데이터분석 첫걸음 시작하기_1기(평생소장용) | 300000.0 | 300000.0 | 0.0 | NaN | PROMOTION | 프로그래밍 | NaT | True |
| 92914 | 1305377.0 | 577873 | 207018.0 | PAYMENT | COMPLETED | K-Digital Credit 빅데이터 분석 첫걸음 시작하기_1기(평생소장용) | 프로그래밍 | B2G | 2021-08-25 00:03:00 | 0.0 | K-Digital Credit 빅데이터분석 첫걸음 시작하기_1기(평생소장용) | 300000.0 | 300000.0 | 0.0 | NaN | PROMOTION | 프로그래밍 | NaT | True |
| 93821 | 1309984.0 | 565650 | 207018.0 | PAYMENT | COMPLETED | K-Digital Credit 빅데이터 분석 첫걸음 시작하기_1기(평생소장용) | 프로그래밍 | B2G | 2021-08-27 14:07:05 | 0.0 | K-Digital Credit 빅데이터분석 첫걸음 시작하기_1기(평생소장용) | 300000.0 | 300000.0 | 0.0 | NaN | PROMOTION | 프로그래밍 | NaT | True |
| 97387 | 1325302.0 | 578212 | 207018.0 | PAYMENT | COMPLETED | K-Digital Credit 빅데이터 분석 첫걸음 시작하기_1기(평생소장용) | 프로그래밍 | B2G | 2021-09-02 16:19:00 | 0.0 | K-Digital Credit 빅데이터분석 첫걸음 시작하기_1기(평생소장용) | 300000.0 | 300000.0 | 0.0 | NaN | PROMOTION | 프로그래밍 | NaT | True |
| 98272 | 1329809.0 | 153064 | 207018.0 | PAYMENT | COMPLETED | K-Digital Credit 빅데이터 분석 첫걸음 시작하기_1기(평생소장용) | 프로그래밍 | B2G | 2021-09-06 09:13:55 | 0.0 | K-Digital Credit 빅데이터분석 첫걸음 시작하기_1기(평생소장용) | 300000.0 | 300000.0 | 0.0 | NaN | PROMOTION | 프로그래밍 | NaT | True |
| 100876 | 1340025.0 | 520784 | 207018.0 | PAYMENT | COMPLETED | K-Digital Credit 빅데이터 분석 첫걸음 시작하기_1기(평생소장용) | 프로그래밍 | B2G | 2021-09-10 16:52:27 | 0.0 | K-Digital Credit 빅데이터분석 첫걸음 시작하기_1기(평생소장용) | 300000.0 | 300000.0 | 0.0 | NaN | PROMOTION | 프로그래밍 | NaT | True |
# sale_pric와 tax_free_amount가 다른 경우
pt[(pt["sale_price"]!= pt["tax_free_amount"])]["course_title"].value_counts()
데이터 사이언스 취업완성 스쿨 17기 79
스프링 아카데미아 36
K-Digital Credit 빅데이터 분석 첫걸음 시작하기_1기(평생소장용) 14
프로모션 : 개발자를 위한 코딩 만능 백과사전 iPad 패키지 (7월 현물 프리패스) 8
프로모션 : 아이패드 200%활용 드로잉 만랩 iPad 패키지 (7월 현물 프리패스) 8
..
(B2B) 노스글로벌 온라인 구독 올 플랜 - 비대면바우처 1
(B2B) 일모작 온라인 구독 올 플랜 - 비대면바우처 1
(B2B) (주)창소프트아이앤아이 온라인 구독 올 플랜 - 비대면바우처 1
(B2B) 주식회사 폴몬 온라인 구독 올 플랜 - 비대면바우처 1
(B2B) (주)오디 온라인 구독 올 플랜 - 비대면바우처 1
Name: course_title, Length: 985, dtype: int64
# 현물 프리패스
pt[(pt["course_title"].str.contains("현물"))]["course_title"].value_counts()
프로모션 : 아이패드 200%활용 드로잉 만랩 iPad 패키지 (7월 현물 프리패스) 8 프로모션 : 개발자를 위한 코딩 만능 백과사전 iPad 패키지 (7월 현물 프리패스) 8 프로모션 : 데이터 분석 맥북 pro 패스(9월 현물 프리패스) 7 프로모션 : 나를 위한 데이터사이언스 백과사전 iPad 패키지 (7월 현물 프리패스) 6 프로모션 : 디자인 맥북 pro 패스(9월 현물 프리패스) 4 프로모션 : 영상 퀄리티를 높이는 전문가 편집스킬 iPad 패키지 (7월 현물 프리패스) 4 프로모션 : 직장인 필수 스킬 맥북 pro 패스(9월 현물 프리패스) 3 프로모션 : 초봉을 바꾸는 주니어를 위한 개발 iPad 패키지 (7월 현물 프리패스) 3 프로모션 : 유튜버 따라잡고 실버버튼 받는 영상 iPad 패키지 (7월 현물 프리패스) 3 프로모션 : 트렌드 완벽정복! 일잘러 마케터 iPad 패키지 (7월 현물 프리패스) 3 프로모션 : 기초부터 다지는 데이터분석 iPad 패키지 (7월 현물 프리패스) 3 프로모션 : 풀스택 개발자 맥북 air 패스(9월 현물 프리패스) 3 프로모션 : 프론트엔드 맥북 pro 패스 (9월 현물 프리패스) 3 프로모션 : 콘텐츠 디자이너를 위한 커리어 백과사전 iPad 패키지 (7월 현물 프리패스) 2 프로모션 : 풀스택 마케터를 위한 마케팅 iPad 패키지 (7월 현물 프리패스) 2 프로모션 : 비 전공자를 위한 프로그래밍 입문 iPad 패키지 (7월 현물 프리패스) 2 프로모션 : 콘텐츠 마케터 맥북 pro 패스(9월 현물 프리패스) 2 프로모션 : 매출을 드라이브 하는 마케팅 백과사전 iPad 패키지 (7월 현물 프리패스) 2 프로모션 : 데이터 분석 맥북 air 패스(9월 현물 프리패스) 2 프로모션 : iOS 개발 맥북 pro 패스(9월 현물 프리패스) 2 프로모션 : 풀스택 마케팅 맥북 air 패스(9월 현물 프리패스) 2 프로모션 : 영상그래픽 디자인 맥북 pro 패스(9월 현물 프리패스) 2 프로모션 : 풀스택 데이터 사이언티스트를 위한 필수 iPad 패키지 (7월 현물 프리패스) 2 프로모션 : MZ세대를 잡아라! SNS 마케팅 트렌드 iPad 패키지 (7월 현물 프리패스) 2 프로모션 : 커리어를 UP! UX/UI 디자인 iPad 패키지 (7월 현물 프리패스) 2 프로모션 : 기초부터 시작하는 데이터분석 프리패스 (5월 삼성 패키지 현물 : 삼성노트북 플러스2) 2 프로모션 : 코딩 LEVEL UP 웹 개발 풀스텍 프리패스 (5월 삼성 패키지 현물 : 삼성 갤럭시 북 프로) 2 프로모션 : 실전 기업투자 맥북 air 패스(9월 현물 프리패스) 1 프로모션 : 프론트엔드 맥북 air 패스 (9월 현물 프리패스) 1 프로모션 : 부동산 재테크 맥북 air 패스 (9월 현물 프리패스) 1 프로모션 : 디자인 맥북 air 패스(9월 현물 프리패스) 1 프로모션 : 게임 디자인 맥북 air 패스(9월 현물 프리패스) 1 프로모션 : 유튜브 영상제작 맥북 pro 패스 (9월 현물 프리패스) 1 프로모션 : 풀스택 개발자 맥북 pro 패스(9월 현물 프리패스) 1 프로모션 : 콘텐츠 마케터 맥북 air 패스(9월 현물 프리패스) 1 프로모션 : 코딩 LEVEL UP 웹 개발 풀스텍 프리패스 (5월 삼성 패키지 현물 : 삼성노트북 플러스2) 1 프로모션 : 부동산 재테크 맥북 pro 패스 (9월 현물 프리패스) - 수정 1 프로모션 : 프론트엔드 끝내기 iPad 패키지 (7월 현물 프리패스) 1 프로모션 : 풀스택 마케터를 위한 마케팅 프리패스 (5월 삼성 패키지 현물 : 삼성 갤럭시 북 프로) 1 프로모션 : 시장의 흐름을 읽는 투자의 정석 프리패스 (5월 삼성 패키지 현물 : 삼성노트북 플러스2) 1 프로모션 : 커리어를 UP UX/UI 디자인 프리패스 (5월 삼성 패키지 현물 : 삼성 갤럭시 북 프로) 1 프로모션 : 워라밸을 완성하는 직장인 필수스킬 프리패스 (5월 삼성 패키지 현물 : 삼성노트북 플러스2) 1 프로모션 : 딥러닝 A to Z까지 한 번에 마스터하는 iPad 패키지 (7월 현물 프리패스) 1 프로모션 : 나의 디자인 DNA찾기! 디자이너를 위한 iPad 패키지 (7월 현물 프리패스) 1 프로모션 : 코딩테스트 결과를 바꾸는 전공생 코딩 iPad 패키지 (7월 현물 프리패스) 1 프로모션 : 칼퇴기원! 실전압축! 직장인 엑셀 iPad 패키지 (7월 현물 프리패스) 1 프로모션 : 영상 퀄리티를 바꿔 줄 영상 제작 스킬 프리패스(5월 삼성 패키지 현물 : 삼성 갤럭시 북 프로) 1 프로모션 : 지금은 마테크가 대세! 매출을 일으키는 마케팅 iPad 패키지 (7월 현물 프리패스) 1 프로모션 : MBA부터 HR까지 직장인 스킬 정복 iPad 패키지 (7월 현물 프리패스) 1 프로모션 : 주니어들을 위한 직장인 스킬 UP iPad 패키지 (7월 현물 프리패스) 1 프로모션 : 시장의 흐름을 읽는 투자의 정석 iPad 패키지 (7월 현물 프리패스) 1 프로모션 : 디지털 마케팅의 끝판왕 콘텐츠 디자인 iPad 패키지 (7월 현물 프리패스) 1 프로모션 : 연봉 앞자리가 바뀌는 앱개발 iPad 패키지 (7월 현물 프리패스) 1 Name: course_title, dtype: int64
# 타겟변수 다시 정제
pt["revenue"] = pt["coupon_title"].isnull() * pt["tax_free_amount"] + ~pt["coupon_title"].isnull() *pt["transaction_amount"]
# revenue가 null값인 경우 transaction amount 로 값 변경(쿠폰은 없지만 tax_free_amount가 null인경우.. 주로 b2b)
pt.loc[pt["revenue"].isnull(),"revenue"] = pt.loc[pt["revenue"].isnull(),"transaction_amount"]
/usr/local/lib/python3.7/dist-packages/ipykernel_launcher.py:2: SettingWithCopyWarning: A value is trying to be set on a copy of a slice from a DataFrame. Try using .loc[row_indexer,col_indexer] = value instead See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy /usr/local/lib/python3.7/dist-packages/pandas/core/indexing.py:1773: SettingWithCopyWarning: A value is trying to be set on a copy of a slice from a DataFrame. Try using .loc[row_indexer,col_indexer] = value instead See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy self._setitem_single_column(ilocs[0], value, pi)
# 수익과 구매 횟수별 pivot table
t = pt.groupby("customer_id").agg({"revenue": "sum","id":'count'}).sort_values(by=["id","revenue"], ascending=False)
t
| revenue | id | |
|---|---|---|
| customer_id | ||
| 98685 | 7040750.0 | 53 |
| 427973 | 0.0 | 47 |
| 158374 | 0.0 | 42 |
| 50769 | 4979110.0 | 39 |
| 3189 | 0.0 | 39 |
| ... | ... | ... |
| 658695 | 0.0 | 1 |
| 659634 | 0.0 | 1 |
| 659805 | 0.0 | 1 |
| 665031 | 0.0 | 1 |
| 666156 | 0.0 | 1 |
37601 rows × 2 columns
t = pt[~pt["coupon_title"].isnull()]
t1 = t[t['coupon_title'].str.contains("검수용")] # 검수용
t2 = t[t['coupon_title'].str.contains("테스트") | t['coupon_title'].str.contains("TEST")] # 테스트
pt = pt.drop(list(t1.index))
t2['coupon_title'].unique()
array(['[무료수강권] CRM팀 테스트용_김경진 개인계정 (이메일 인증 안 된 계정)', '[내부직원] 테스트용 결제 쿠폰',
'테스트쿠폰', 'TEST이제너두_직장인을 위한 파이썬 데이터 분석', 'TEST',
'[무료수강권] 초격차 패키지: 한 번에 끝내는 코딩테스트 369 Java편_이준희 강사님', '호준 테스트',
'이웅모 강사님 강의 준비용 쿠폰 발급_초격차 패키지 : 한 번에 끝내는 코딩테스트 369 Java편',
'[테스트쿠폰] 네이버 페이 간편결제 테스트용 쿠폰', '테스트_전지현', '[CX] 관리자 외 계정 테스트용',
'테스트', '[cs팀] 테스트 결제 위한 쿠폰 발급',
'[30%쿠폰] The RED 고객 경험을 개선하는 A/B테스트 기반 모바일 앱 개발 신규 강의 할인'],
dtype=object)
t3 = t2.loc[~t2['coupon_title'].str.startswith("[30%쿠폰]")]
t3 = t3.drop(33173) # 이준희 강사
pt = pt.drop(list(t3.index))
df[df["transaction_amount"]==0]["coupon_title"].unique()
array(['한 번에 끝내는 Java/Sring 웹 개발 마스터 초격차 패키지 무료 쿠폰 (-2/28)',
'수강생 50만명 돌파 기념 감사제 쿠폰', '[웰컴쿠폰] 올인원 패키지 1만원 할인 쿠폰',
'올인원 패키지 : 타이포그래피와 편집디자인 강의 수강권', '[무료수강권] 강의 검수용_이호상 PM님',
'패캐머_온라인 쿠폰 !',
'[무료수강권] 파이낸스 카테고리 올인원 패키지_대체투자 자산운용 실무 영상 오픈 일정 변경',
'한 번에 끝내는 반복 업무 자동화 초격차 패키지 사용 가능 쿠폰', 'crm 검수용 쿠폰 aop',
'[럭키룰렛] 올인원패키지', '[무료수강권] 강의검수용_강사님 쿠폰_박혜린 강사님', '신해동 발행 쿠폰',
'[무료수강권] 강사님 제공용 RED', '[무료수강권] 강사님 제공용', '[무료수강권] 내부직원 검수용 RED',
'[무료수강권] 올인원 패키지 : 인스타를 성장시킨 50명의 성공 방정식 강의검수용_강사님 쿠폰',
'[무료수강권] 내부직원 강의 검수용',
'[무료수강권] 권오상 회계사의 자금조달 분석 및 가치평가_23기 신동현 수강생님', nan,
'[무료수강권] 완주반 후기 리워드', 'Vue.js 압축 완성 강의',
'[무료수강권] CRM팀 테스트용_김경진 개인계정 (이메일 인증 안 된 계정)',
'이지웰 쿠폰_직장인 필수 스킬 3종 세트 MAX', '올인원 패키지 보상 쿠폰 1', '올인원 패키지 보상 쿠폰 2',
'[무료수강권] 파이썬 웹 개발 올인원 패키지_조성준 강사님', '[폐강 보상] 온라인 완주반 100% 할인 쿠폰',
'[무료수강권] 권오상 회계사의 금융 아카데미 - 재무제표 기초',
'[무료수강권] 머신러닝과 데이터 분석 A to Z', '패캐머_온라인 쿠폰',
'서포터즈 1기 리워드 (유니티 게임 포트폴리오 완성)',
'서포터즈 1기 리워드 (인스타를 성장시킨 50명의 성공방정식)',
'서포터즈 1기 리워드 (한번에 끝내는 영상 촬영과 편집)',
'서포터즈 1기 리워드 (100억을 움직이는 단 10장의 PPT)',
'서포터즈 1기 리워드 (FAST MBA 2020 )', '서포터즈 1기 리워드 (완전정복! 시각디자인 기초)',
'서포터즈 1기 리워드 (파이썬 웹 개발)', '서포터즈 1기 리워드 (디지털 마케팅 MAX)',
'서포터즈 1기 리워드 (퀴즈처럼 풀면서 배우는 파이썬 머신러닝 300제+)',
'서포터즈 1기 리워드 (타이포그래피와 편집디자인 by 인디자인(Indesign))',
'패캐머_온라인 쿠폰! (CRM팀)', '서포터즈 1기 리워드 (구글 애널리틱스)',
'서포터즈 전용 | 한번에 끝내는 영상 촬영과 편집 초격차 패키지 무료 수강 쿠폰',
'서포터즈 전용 | 디지털 마케팅 MAX 올인원 패키지 무료 수강 쿠폰',
'서포터즈 전용 | 한 번에 끝내는 데이터 분석 툴 초격차 패키지 무료 수강 쿠폰',
'서포터즈 전용 | 100억을 움직이는 단 10장의 PPT 올인원 패키지 무료 수강 쿠폰',
'서포터즈 1기 리워드 (십분만에 끝낸다 십다 프리미어)',
'서포터즈 전용 | 한 번에 끝내는 모션그래픽 초격차 패키지 무료 수강 쿠폰',
'서포터즈 전용 | 한번에 끝내는 Java/Spring 웹 개발 마스터 초격차 패키지 무료 수강 쿠폰',
'서포터즈 전용 | 한 번에 끝내는 디자인 툴 초격차 패키지 무료 수강 쿠폰',
'[무료수강권] 한번에 끝내는 UX/UI 디자인 초격차_김수윤 강사님',
'프로젝트로 배우는 부동산 PF 17기_REC.ON:VC', '[무료수강권] 데이터 기반 마케팅_박선민 강사님',
'[무료수강권] 내부직원용', '샘플', '주니버시티 리워드 : 올인원 패키지_이커머스 데이터 분석 무료수강권',
'주니버시티 리워드 : 올인원 패키지 무료수강권 1매',
'[무료수강권] 파이썬을 활용한 이커머스 데이터 분석_데이터분석 거북이반_박솔 수강생님',
'[무료수강권] 파이썬을 활용한 이커머스 데이터 분석_데이터분석 꼬끼오반_이진희 수강생님',
'[무료수강권] 엑셀언니의 사무실용 엑셀뿌수기_황인영 강사님',
'[무료수강권] 기업가치평가와 M&A 전략 실무_황인영 강사님',
'[무료수강권] 파이썬을 활용한 이커머스 데이터 분석_데이터분석 올빼미반', '올인원 패키지 : 딥러닝/인공지능',
'[내부직원] 테스트용 결제 쿠폰', '[무료수강권] 초격차 패키지: 한 번에 끝내는 디자인 툴_윤소라 CM님',
'[무료수강권] 마디아의 UX/UI 포트폴리오_마디아(이승훈) 강사님', '올인원 패키지 : 모두를 위한 SQL/DB',
'스프링 아카데미아 자유이용 수강권 (강의 1)', '스프링 아카데미아 자유이용 수강권 (강의 2)',
'[무료수강권] AOP 강의 검수용_어효경님', '[무료수강권] 권오상 회계사의 자금조달 및 가치평가_내부 검수용',
'[무료수강권] 파이썬을 활용한 이커머스 데이터 분석_데이터분석 꼬끼오반_임유진 수강생님',
'[무료수강권] 파이썬 웹 개발 올인원 패키지_이은찬 강사님',
'[무료수강권] 올인원 패키지 (일부 강의 제외)_박솔 수강생님', '이지웰 쿠폰_직장인 회계 첫걸음',
'[무료수강권] 파이썬을 활용한 시계열 데이터 분석 A-Z_완주반 리워드_김혁진 수강생님',
'[무료수강권] 내부 직원용_김준홍님',
'[무료수강권] AWS/Docker 실전 클라우드 서버 구축 올인원 패키지_완주반 리워드_박진용 수강생님',
'[무료수강권] 모두를 위한 SQL/DB 올인원 패키지_박원빈 강사님', '올인원패키지 수강 쿠폰', '신해동 쿠폰',
'[무료수강권] 강의 검수용 무료 수강권 (패캐머용)', '이지웰 쿠폰_부동산 투자', '예스폼 검수용 쿠폰',
'테스트쿠폰', '[무료수강권] 캐글 1위와 풀어보는 머신러닝 입문 트레이닝', '4월 1+1 페이백 이벤트 쿠폰',
'[무료수강권] 소금툰과 함께 캐릭터 드로잉/굿즈/임티/컷툰_진정민 강사님', '업무용',
'[무료수강권] 한 번에 끝내는 데이터 분석 툴 초격차 패키지_김유석 강사님',
'[무료수강권] 모두를 위한 SQL/DB 올인원 패키지_김유석 강사님', '완주반 코스 등록 쿠폰',
'[무료수강권] 권오상의 금융 아카데미 - 재무제표 분석 심화_재무제표 분석 23기 수강생용',
'[무료수강권] 강의 검수용_조은주 매니저님',
'[무료수강권] 올인원 패키지 (일부 강의 제한)_주니버시티: 데이터분석 거북이반_홍정기 수강생님',
'[무료수강권] 시각디자인 기초_이진우, 최세진 강사님',
'[무료수강권] The RED: 프론트엔드 Back to the Basic (by 김태곤)',
'강의 제작 참고용 (강사님)', '[무료수강권] 강사님 지인 제공용',
'[무료수강권] RED 검수용_지민정 매니저님',
'[무료수강권] 업무자동화 MAX_업무자동화 수강후기 작성_김동규 수강생님',
'[무료수강권] 한번에 끝내는 데이터 분석 툴',
'한 번에 끝내는 Java/Sring 웹 개발 마스터 초격차 패키지 무료 쿠폰',
'[무료수강권] 강의 검수용_하수진 매니저님', '[무료수강권] 부동산 디벨로퍼', '[무료수강권] 부동산 투자',
'스프링 아카데미아 자유이용 수강권 (강의 4)', '[특별쿠폰] 올인원 패키지 : Node 웹 프로그래밍 구매자',
'[무료수강권] 모델 성능 개선으로 익히는 강화 학습_김성제 강사님',
'TEST이제너두_직장인을 위한 파이썬 데이터 분석',
'[무료수강권] 퀴즈처럼 풀면서 배우는 파이썬 머신러닝 300제_데이터분석 올빼미반',
'서포터즈 전용 | 완전정복! 시각디자인 기초 올인원 패키지 무료 수강 쿠폰 (장희란님)',
'[무료수강권] 내부 직원 강의 검수용',
'아이패드 배송 지연 보상 온라인 100% 할인 쿠폰 (중복 3회 사용 가능)',
'[무료수강권] 김민태의 프론트 아카데미 제 1강_박은종 강사님', 'TEST',
'[무료수강권] AOP 수강권_이동근 PD님',
'[무료수강권] 초격차 패키지: 한 번에 끝내는 코딩테스트 369 Java편_이준희 강사님',
'[무료수강권] 강사님 제공용_올인원 패키지', '스프링 아카데미아 자유이용 수강권 (강의 3)',
'[무료수강권] RED 강의 검수용_홍승희 매니저님', '[무료수강권] 강의 검수용_최현우 매니저님',
'[무료수강권] 강의 검수용_이호상 PM님 (RED)',
'[무료수강권] 올인원 패키지 (일부 강의 제한)_주니버시티: JS&React 거북이반_김은해 수강생님 (1)',
'[무료수강권] 올인원 패키지 : 소금툰과 함께 캐릭터 드로잉/굿즈/임티/컷툰_장혜리 매니저님',
'올인원 패키지 : 컴퓨터공학 전공 필수', '[무료수강권] 초격차 패키지: 한 번에 끝내는 디자인 툴_이우철 강사님',
'글담X패스트캠퍼스 무료수강권 제공 이벤트 쿠폰',
'초격차패키지 : 이지쌤과 한번에 끝내는 실무 PPT 강사검수용쿠폰 - 이지쌤',
'[무료수강권] 완전정복! 시각디자인 기초_박부미 강사님', '호준 테스트',
'이웅모 강사님 강의 준비용 쿠폰 발급_올인원 패키지 : 김민태의 프론트엔드 아카데미 : 제 1강 JavaScript & TypeScript Essential',
'이웅모 강사님 강의 준비용 쿠폰 발급_초격차 패키지 : 한 번에 끝내는 node.js 웹 프로그래밍',
'이웅모 강사님 강의 준비용 쿠폰 발급_초격차 패키지 : 한 번에 끝내는 코딩테스트 369 Java편',
'[무료수강권] 초격차 패키지: 30개 프로젝트로 배우는 Android 앱 개발 with Kotlin_이기정 강사님',
'10분 컷 100% 할인 쿠폰', '[무료수강권] GA4 탑재, 구글 애널리틱스 끝장내기_최윤정 마케터님',
'[무료수강권] 30개 프로젝트로 배우는 Android 앱 개발_최종원 강사님',
'[무료수강권] iOS 앱 개발 올인원 패키지_최종원 강사님',
'[패스트캠퍼스] 올인원 패키지: 컴퓨터 공학 전공_박용현 강사님',
'[무료수강권] GA4 탑재, 구글 애널리틱스 끝장내기_안혜진 강사님',
'스프링 아카데미아 자유이용 수강권 (강의 5)', '이제너두_영상 제작편집', 'PM 내부직원 강의 검수용 무료쿠폰',
'[무료수강권] 부동산 투자_이해진 강사님', '강의 검수용 강사 무료수강쿠폰',
'이제너두_직장인을 위한 파이썬 데이터 분석',
'[서포터즈 전용] 소금툰과 함께 캐릭터 드로잉/굿즈/임티/컷툰 무료 수강',
'[서포터즈 전용] Financial Modeling 무료 수강',
'[서포터즈 전용] 재무/세무 회계 실무 완성 무료 수강',
'[서포터즈 전용] 한 번에 끝내는 node.js 웹 프로그래밍 무료 수강',
'[서포터즈 전용] 파이썬 기초부터 시작하는 딥러닝 영상인식 무료 수강',
'[서포터즈 전용] 완전정복 시각디자인 기초 무료 수강',
'[서포터즈 전용] 바다가 알려주는 감성가득 영상 제작 무료 수강',
'[서포터즈 전용] 피피티프로젝트의 누구나 쉽게 배우는 시선강탈 피피티 디자인 무료 수강',
'[서포터즈 전용] GA4 탑재, 구글 애널리틱스 끝장내기 무료 수강', '[무료수강권] RED 검수용_공정필 PM님',
'[무료수강권] 한 번에 끝내는 Java/Spring 웹 개발 마스터 초격차 패키지_안성훈 강사님',
'[무료수강권] 김재하 강사님', '[무료수강권] 박지우 강사님',
'[무료수강권] 올인원 패키지 (일부 강의 제한)_주니버시티: 데이터분석 거북이반_이선율 수강생님',
'[무료수강권] core MBA_결제 메일 확인용', '[무료수강권] 토지개발_김민근 강사님',
'[무료수강권] 부동산 마케팅_김민근 강사님', '[무료수강권] 인허가_김민근 강사님',
'[무료수강권] 대체투자 자산운용 실무_김민근 강사님', '[무료수강권] 주거용 수익형 부동산 개발_김민근 강사님',
'[무료수강권] 통계와 엑셀을 활용한 데이터 분석_이민규 강사님', '5월 페이백 프로모션 쿠폰',
'[서포터즈 전용] 재무/세무 회계 실무 완성 무료 수강 (유현경님)', '[무료수강권] 강의 참고용 발행_강사님',
'[테스트쿠폰] 네이버 페이 간편결제 테스트용 쿠폰', '디지털 마케팅 MAX 무료 수강 쿠폰 (신수현)',
'[무료수강권] 완전정복! 시각디자인 기초_김진희 강사님', '테스트_전지현',
'[무료수강권] 디지털 마케팅 MAX 2020_이민규 강사님', '강의 제작 참고용', '[무료수강권] 유민상 강사님',
'특별 할인 쿠폰(신해동)', '개발실 동영상 시청 기록 점검용', '[일주일한정] 플러스 친구 1만원 즉시할인 쿠폰',
'[무료수강권] 올인원 패키지 수강권_서영웅 강사님', 'RED 이동주님 강의 참고용 쿠폰',
'[무료수강권] 15명의 전문 애널리스트에게 배우는 산업&매크로 분석과 투자 전략', '마케팅 강의 검수용 쿠폰 발급',
'올인원 패키지 : 네트워크와 보안 핵심 요약', '신해동 발행 쿠폰 (~21. 08. 31)',
'[무료수강권] 남진현 강사님', 'CRM_RED 검수용 쿠폰', '[무료수강권] CX팀 검수용_승희님',
'[체험단 전용] 엑셀유치원 100% 무료 수강 쿠폰', '6월 반값특가 프로모션 쿠폰',
'이제너두_직장인 회계 첫걸음', '[서포터즈 쿠폰] 한 번에 끝내는 반복 업무 자동화 초격차 패키지 무료 수강',
'마케팅 GA 쿠폰',
'[100%할인]The RED : 백발의 개발자를 꿈꾸며 : 코드리뷰, 레거시와 TDD by 백명석, 최범균',
'[무료수강권] 강사님 제공 무료 수강권', '[무료수강권] 내부직원용_AOP_허지은 PD님',
'[무료수강권] 내부직원용_AOP_김인지 PD님', '[무료수강권] 내부직원용_RED_성정화 PD님',
'[무료수강권] 겨울서점X패스트캠퍼스_유튜브 댓글 이벤트 당첨자', '[무료수강권] 내부직원용_RED_허지은 PD님',
'강사 검수용 쿠폰 : 전다정 강사님', '[WELCOME] 온라인 강의 1만원 할인쿠폰',
'[CX] 관리자 외 계정 테스트용', '김영하 강의 후기 쿠폰', '[내부검수용] RED: 김영하_담당 PM님',
'내부 직원 검수용 쿠폰', '테스트', '강의 참고용 쿠폰 : 최현우님',
'[무료수강권] 강사님 제공용_The RED 김민태',
'[무료수강권] Financial Modleing 기수강생 대상 신규 강의 주제 소요 조사 추첨자',
'[무료수강쿠폰] 엑셀 유치원 이재형 강사님 검수용 쿠폰', 'RED 강의 참고용 쿠폰',
'[체험단 전용] 엑셀유치원 100% 무료 수강 쿠폰 재발급', '이제너두_직장인 필수 스킬 3종 세트',
'[무료수강권] 강의 제공용 발행', '[100% 무료쿠폰] 산업&매크로 분석_무료쿠폰',
'아이패드 패키지 배송 지연 리워드',
'[서포터즈 전용] 6개월 치 업무를 하루 만에 끝내는 업무자동화 무료 수강 쿠폰',
'[서포터즈 전용] Java/Spring 웹 개발 마스터 무료 수강 쿠폰',
'[서포터즈 전용] 한번에 끝내는 파이썬 웹 개발 무료 수강 쿠폰',
'[서포터즈 전용] 완전정복! 시각디자인 기초 무료 수강 쿠폰',
'[서포터즈 전용] 100억을 움직이는 단 10장의 PPT 무료 수강 쿠폰', '2021 콘텐츠상품기획인턴 쿠폰',
'7월 100% 페이백 프로모션 쿠폰',
'올인원 패키지 : 김민태의 프론트엔드 아카데미 : 제 1강 JavaScript & TypeScript Essential',
'[무료 수강권] 강사제공용 쿠폰', '7월 100% 페이백 프로모션 쿠폰_복구',
'[무료수강권] 강사님 제공용_The RED', '이제너두_부동산 투자',
'[무료수강권] 강의 참고용 발행_양세열 강사님', '[무료수강권] 강사님 지인 무료 수강권',
'K-Digital Credit 머신러닝 & AI 첫걸음 시작하기_1기(평생소장용) 쿠폰',
'K-Digital Credit 빅데이터분석 첫걸음 시작하기_1기(평생소장용)',
'The RED : 조은의 프론트엔드 실무 가이드 : 요구사항 분석과 적정 기술_무료결제쿠폰',
'K-Digital Credit 머신러닝 & AI 첫걸음 시작하기_1기(평생소장용)',
'일잘러 필수스킬 모음집 .ZIP 내부직원 검수용 쿠폰', '신해동 100% 할인 쿠폰',
'K-Digital Credit 프로그래밍 첫걸음 시작하기_1기(평생소장용)',
'K-Digital Credit 나만의 iOS 앱 개발 입문_1기(평생소장용)', '[무료수강권] 외주업체 제공용',
'[무료수강권] 내부직원용_RED_김인지 PD님', '[무료수강권] 강사 소속법인 임직원 제공',
'[cs팀] 테스트 결제 위한 쿠폰 발급', 'RED 강연 참고용 쿠폰 (김상우님)',
'[무료수강권] 강의 참고용 발행_내부직원검수용', '[무료수강권] 내부직원용_AOP_성정화 PD님',
'[수강생 리워드] 완주를 축하합니다! / 올인원패키지 : 알고리즘 기술 면접 완전 정복 100% 할인 쿠폰',
'[무료수강권] 금융아카데미: 권오상 회계사의 자금조달 및 가치평가', '[내부검수용] RED 강의 검수용 쿠폰',
'이제너두_해외소싱으로 온라인 커머스 정복하기', '8월 1+1 프로모션 쿠폰',
'[예외처리]연습문제 패키지 : 퀴즈처럼 풀면서 배우는 파이썬 머신러닝 300제+',
'[무료수강권] 강의 참고용 발행_다회권', '[무료수강권] 강의 참고용 발행_안성훈 강사님',
'[무료수강권] 강사님 제공용_AWS로DevOps', '강의 검수용 강사 무료수강쿠폰 -김윤후님',
'[특별쿠폰]컴퓨터공학 올인원 패키지 기수강생 100% 할인쿠폰',
'K-Digital Credit 빅데이터 분석 첫걸음 시작하기_2기(평생소장용)',
'K-Digital Credit 프로그래밍 첫걸음 시작하기_2기(평생소장용)',
'SB_네카라쿠배 강사학습용_김데레사 강사님', '[검수용] CX 검수용 쿠폰',
'MacBook Pass 수강생 감사 100% 할인 쿠폰'], dtype=object)
t = pt[~pt["coupon_title"].isnull()]
t_del = t[t['coupon_title'].str.contains("패캐머")]
t_del["coupon_title"].unique()
array(['패캐머_온라인 쿠폰 !', '패캐머_온라인 쿠폰', '패캐머_온라인 쿠폰! (CRM팀)'], dtype=object)
pt = pt.drop(list(t_del.index))
t = pt[(~pt["coupon_title"].isnull())&(pt["transaction_amount"]==0)]
t_del = t[t['coupon_title'].str.contains("제공")]
t_del["coupon_title"].unique()
array(['[무료수강권] 강사님 제공용 RED', '[무료수강권] 강사님 제공용', '[무료수강권] 강사님 지인 제공용',
'[무료수강권] 강사님 제공용_올인원 패키지', '글담X패스트캠퍼스 무료수강권 제공 이벤트 쿠폰',
'[무료수강권] 강사님 제공 무료 수강권', '[무료수강권] 강사님 제공용_The RED 김민태',
'[무료수강권] 강의 제공용 발행', '[무료 수강권] 강사제공용 쿠폰',
'[무료수강권] 강사님 제공용_The RED', '[무료수강권] 외주업체 제공용',
'[무료수강권] 강사 소속법인 임직원 제공', '[무료수강권] 강사님 제공용_AWS로DevOps'],
dtype=object)
pt = pt.drop(list(t_del.index))
t = pt[(~pt["coupon_title"].isnull())&(pt["transaction_amount"]==0)]
t_del = t[t['coupon_title'].str.contains("샘플")]
t_del["coupon_title"].unique()
array(['샘플'], dtype=object)
pt = pt.drop(list(t_del.index))
t = pt[(~pt["coupon_title"].isnull())&(pt["transaction_amount"]==0)]
t_del = t[t['coupon_title'].str.contains("내부")]
t_del["coupon_title"].unique()
array(['[무료수강권] 내부직원용', '[무료수강권] 내부 직원용_김준홍님',
'[무료수강권] 내부직원용_AOP_허지은 PD님', '[무료수강권] 내부직원용_AOP_김인지 PD님',
'[무료수강권] 내부직원용_RED_성정화 PD님', '[무료수강권] 내부직원용_RED_허지은 PD님',
'[무료수강권] 내부직원용_RED_김인지 PD님', '[무료수강권] 내부직원용_AOP_성정화 PD님'],
dtype=object)
pt = pt.drop(list(t_del.index))
t = pt[(~pt["coupon_title"].isnull())&(pt["transaction_amount"]==0)]
t_del = t[t['coupon_title'].str.contains("참고용")]
t_del["coupon_title"].unique()
array(['강의 제작 참고용 (강사님)', '[무료수강권] 강의 참고용 발행_강사님', '강의 제작 참고용',
'RED 이동주님 강의 참고용 쿠폰', '강의 참고용 쿠폰 : 최현우님', 'RED 강의 참고용 쿠폰',
'[무료수강권] 강의 참고용 발행_양세열 강사님', 'RED 강연 참고용 쿠폰 (김상우님)',
'[무료수강권] 강의 참고용 발행_다회권', '[무료수강권] 강의 참고용 발행_안성훈 강사님'], dtype=object)
pt = pt.drop(list(t_del.index))
t = pt[(~pt["coupon_title"].isnull())&(pt["transaction_amount"]==0)]
t_del = t[t['coupon_title'].str.contains("신해동")]
t_del["coupon_title"].unique()
array(['신해동 발행 쿠폰', '신해동 쿠폰', '특별 할인 쿠폰(신해동)', '신해동 발행 쿠폰 (~21. 08. 31)',
'신해동 100% 할인 쿠폰'], dtype=object)
pt = pt.drop(list(t_del.index))
t = pt[(~pt["coupon_title"].isnull())&(pt["transaction_amount"]==0)]
t_del = t[t['coupon_title'].str.contains("예외")]
t_del["coupon_title"].unique()
array(['[예외처리]연습문제 패키지 : 퀴즈처럼 풀면서 배우는 파이썬 머신러닝 300제+'], dtype=object)
pt = pt.drop(list(t_del.index))
t = pt[(~pt["coupon_title"].isnull())&(pt["transaction_amount"]==0)]
t_del = t[t['coupon_title'].str.contains("업무용")]
t_del["coupon_title"].unique()
array(['업무용'], dtype=object)
pt = pt.drop(list(t_del.index))
t = pt[(~pt["coupon_title"].isnull())&(pt["transaction_amount"]==0)]
t_del = t[t['coupon_title'].str.contains("매니저")]
t_del["coupon_title"].unique()
array(['[무료수강권] 올인원 패키지 : 소금툰과 함께 캐릭터 드로잉/굿즈/임티/컷툰_장혜리 매니저님'],
dtype=object)
pt = pt.drop(list(t_del.index))
t = pt[(~pt["coupon_title"].isnull())&(pt["transaction_amount"]==0)]
t_del = t[t['coupon_title'].str.contains("PD")]
t_del["coupon_title"].unique()
array(['[무료수강권] AOP 수강권_이동근 PD님'], dtype=object)
pt = pt.drop(list(t_del.index))
t = pt[(~pt["coupon_title"].isnull())&(pt["transaction_amount"]==0)]
t_del = t[t['coupon_title'].str.contains("강사님")]
t_del["coupon_title"].unique()
array(['[무료수강권] 파이썬 웹 개발 올인원 패키지_조성준 강사님',
'[무료수강권] 한번에 끝내는 UX/UI 디자인 초격차_김수윤 강사님',
'[무료수강권] 데이터 기반 마케팅_박선민 강사님', '[무료수강권] 엑셀언니의 사무실용 엑셀뿌수기_황인영 강사님',
'[무료수강권] 기업가치평가와 M&A 전략 실무_황인영 강사님',
'[무료수강권] 마디아의 UX/UI 포트폴리오_마디아(이승훈) 강사님',
'[무료수강권] 파이썬 웹 개발 올인원 패키지_이은찬 강사님',
'[무료수강권] 모두를 위한 SQL/DB 올인원 패키지_박원빈 강사님',
'[무료수강권] 소금툰과 함께 캐릭터 드로잉/굿즈/임티/컷툰_진정민 강사님',
'[무료수강권] 한 번에 끝내는 데이터 분석 툴 초격차 패키지_김유석 강사님',
'[무료수강권] 모두를 위한 SQL/DB 올인원 패키지_김유석 강사님',
'[무료수강권] 시각디자인 기초_이진우, 최세진 강사님',
'[무료수강권] 모델 성능 개선으로 익히는 강화 학습_김성제 강사님',
'[무료수강권] 김민태의 프론트 아카데미 제 1강_박은종 강사님',
'[무료수강권] 초격차 패키지: 한 번에 끝내는 코딩테스트 369 Java편_이준희 강사님',
'[무료수강권] 초격차 패키지: 한 번에 끝내는 디자인 툴_이우철 강사님',
'[무료수강권] 완전정복! 시각디자인 기초_박부미 강사님',
'이웅모 강사님 강의 준비용 쿠폰 발급_올인원 패키지 : 김민태의 프론트엔드 아카데미 : 제 1강 JavaScript & TypeScript Essential',
'이웅모 강사님 강의 준비용 쿠폰 발급_초격차 패키지 : 한 번에 끝내는 node.js 웹 프로그래밍',
'[무료수강권] 초격차 패키지: 30개 프로젝트로 배우는 Android 앱 개발 with Kotlin_이기정 강사님',
'[무료수강권] 30개 프로젝트로 배우는 Android 앱 개발_최종원 강사님',
'[무료수강권] iOS 앱 개발 올인원 패키지_최종원 강사님',
'[패스트캠퍼스] 올인원 패키지: 컴퓨터 공학 전공_박용현 강사님',
'[무료수강권] GA4 탑재, 구글 애널리틱스 끝장내기_안혜진 강사님', '[무료수강권] 부동산 투자_이해진 강사님',
'[무료수강권] 한 번에 끝내는 Java/Spring 웹 개발 마스터 초격차 패키지_안성훈 강사님',
'[무료수강권] 김재하 강사님', '[무료수강권] 박지우 강사님', '[무료수강권] 토지개발_김민근 강사님',
'[무료수강권] 부동산 마케팅_김민근 강사님', '[무료수강권] 인허가_김민근 강사님',
'[무료수강권] 대체투자 자산운용 실무_김민근 강사님', '[무료수강권] 주거용 수익형 부동산 개발_김민근 강사님',
'[무료수강권] 통계와 엑셀을 활용한 데이터 분석_이민규 강사님',
'[무료수강권] 완전정복! 시각디자인 기초_김진희 강사님',
'[무료수강권] 디지털 마케팅 MAX 2020_이민규 강사님', '[무료수강권] 유민상 강사님',
'[무료수강권] 올인원 패키지 수강권_서영웅 강사님', '[무료수강권] 남진현 강사님',
'[무료수강권] 강사님 지인 무료 수강권', 'SB_네카라쿠배 강사학습용_김데레사 강사님'], dtype=object)
pt = pt.drop(list(t_del.index))
# format의 경우 null값이 없음 -> 곧바로 전처리
pt.isnull().sum()
id 0 customer_id 0 course_id 1978 type 0 state 0 course_title 0 category_title 0 format 0 completed_at 0 transaction_amount 0 coupon_title 26852 coupon_discount_amount 26852 sale_price 1065 tax_free_amount 1065 pg 7916 method 0 subcategory_title 0 marketing_start_at 8773 purchased 0 revenue 0 dtype: int64
# b2b 테이블 추출
df_b2b = pt[pt['format'].str.contains("B2B")]
df_b2b
| id | customer_id | course_id | type | state | course_title | category_title | format | completed_at | transaction_amount | coupon_title | coupon_discount_amount | sale_price | tax_free_amount | pg | method | subcategory_title | marketing_start_at | purchased | revenue | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 631 | 972364.0 | 478743 | 204039.0 | PAYMENT | COMPLETED | (B2B) 힐코코리아 온라인 구독 올 플랜 - 패파입주사 | 교육 | B2B 온라인 | 2021-03-29 08:52:36 | 100000.0 | NaN | NaN | NaN | NaN | NaN | TRANSFER | 교육 | NaT | True | 100000.0 |
| 633 | 972365.0 | 478745 | 203352.0 | PAYMENT | COMPLETED | (B2B) 주식회사 루나 온라인 구독 ALL PLAN - 패파입주사 | 교육 | B2B 온라인 | 2021-03-29 08:57:12 | 750000.0 | NaN | NaN | NaN | NaN | NaN | TRANSFER | 교육 | NaT | True | 750000.0 |
| 1035 | 973331.0 | 479082 | 204387.0 | PAYMENT | COMPLETED | (B2B) 현대백화점 온라인 구독 올 플랜 | 교육 | B2B 온라인 | 2021-03-29 13:01:32 | 600000.0 | NaN | NaN | 600000.0 | 600000.0 | NaN | CARD | 교육 | NaT | True | 600000.0 |
| 1046 | 973363.0 | 474327 | 204387.0 | PAYMENT | COMPLETED | (B2B) 현대백화점 온라인 구독 올 플랜 | 교육 | B2B 온라인 | 2021-03-29 13:08:38 | 600000.0 | NaN | NaN | 600000.0 | 600000.0 | NaN | CARD | 교육 | NaT | True | 600000.0 |
| 1135 | 973592.0 | 479185 | 204387.0 | PAYMENT | COMPLETED | (B2B) 현대백화점 온라인 구독 올 플랜 | 교육 | B2B 온라인 | 2021-03-29 14:13:27 | 600000.0 | NaN | NaN | 600000.0 | 600000.0 | NaN | CARD | 교육 | NaT | True | 600000.0 |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 104831 | 1361297.0 | 669386 | 207667.0 | PAYMENT | COMPLETED | (B2B) 건강한선택권 온라인 구독 올 플랜 - 비대면바우처 | 교육 | B2B 온라인 | 2021-09-23 15:04:56 | 390000.0 | NaN | NaN | NaN | NaN | NaN | TRANSFER | 교육 | NaT | True | 390000.0 |
| 104832 | 1361312.0 | 669400 | 207555.0 | PAYMENT | COMPLETED | (B2B) 케리케이온 온라인 구독 올 플랜 - 비대면바우처 | 교육 | B2B 온라인 | 2021-09-23 15:04:56 | 1200000.0 | NaN | NaN | NaN | NaN | NaN | TRANSFER | 교육 | NaT | True | 1200000.0 |
| 104905 | 1367252.0 | 672301 | 207714.0 | PAYMENT | COMPLETED | (B2B) (주)공정씨컴퍼니 온라인 구독 올 플랜 - 비대면바우처 | 교육 | B2B 온라인 | 2021-09-23 17:33:18 | 2000000.0 | NaN | NaN | NaN | NaN | NaN | ONSITE | 교육 | NaT | True | 2000000.0 |
| 105163 | 1367258.0 | 672307 | 207731.0 | PAYMENT | COMPLETED | (B2B) 그린오션스 온라인 구독 올 플랜 - 비대면바우처 | 교육 | B2B 온라인 | 2021-09-24 14:26:08 | 600000.0 | NaN | NaN | NaN | NaN | NaN | ONSITE | 교육 | NaT | True | 600000.0 |
| 105265 | 1367259.0 | 672308 | 207742.0 | PAYMENT | COMPLETED | (B2B) (주)오디 온라인 구독 올 플랜 - 비대면바우처 | 교육 | B2B 온라인 | 2021-09-24 18:17:10 | 600000.0 | NaN | NaN | NaN | NaN | NaN | ONSITE | 교육 | NaT | True | 600000.0 |
1314 rows × 20 columns
# b2g 테이블 추출
df_b2g = pt[pt['format'].str.contains("B2G")]
df_b2g
| id | customer_id | course_id | type | state | course_title | category_title | format | completed_at | transaction_amount | coupon_title | coupon_discount_amount | sale_price | tax_free_amount | pg | method | subcategory_title | marketing_start_at | purchased | revenue | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 76521 | 1228790.0 | 467567 | 205419.0 | PAYMENT | COMPLETED | (B2B) K-Digital Training 핀테크 서비스 프론트엔드 개발 과정 1기 | 프로그래밍 | B2G | 2021-07-20 12:32:15 | 859290.0 | NaN | NaN | 859290.0 | 859290.0 | INICIS | CARD | 프로그래밍 | NaT | True | 859290.0 |
| 84609 | 1267969.0 | 623766 | 206746.0 | PAYMENT | COMPLETED | (B2B) K-Digital Credit 프로그래밍 첫걸음 시작하기_4기 | 프로그래밍 | B2G | 2021-08-06 07:36:20 | 20000.0 | NaN | NaN | 20000.0 | 20000.0 | KAKAO | CARD | 프로그래밍 | NaT | True | 20000.0 |
| 84732 | 1268687.0 | 622246 | 206847.0 | PAYMENT | COMPLETED | (B2B) K-Digital Credit 빅데이터 분석 첫걸음 시작하기_4기 | 프로그래밍 | B2G | 2021-08-06 15:01:04 | 30000.0 | NaN | NaN | 30000.0 | 30000.0 | INICIS | CARD | 프로그래밍 | NaT | True | 30000.0 |
| 84819 | 1269278.0 | 33540 | 206847.0 | PAYMENT | COMPLETED | (B2B) K-Digital Credit 빅데이터 분석 첫걸음 시작하기_4기 | 프로그래밍 | B2G | 2021-08-06 19:35:52 | 30000.0 | NaN | NaN | 30000.0 | 30000.0 | INICIS | CARD | 프로그래밍 | NaT | True | 30000.0 |
| 84944 | 1270030.0 | 625050 | 206847.0 | PAYMENT | COMPLETED | (B2B) K-Digital Credit 빅데이터 분석 첫걸음 시작하기_4기 | 프로그래밍 | B2G | 2021-08-07 13:12:13 | 30000.0 | NaN | NaN | 30000.0 | 30000.0 | INICIS | CARD | 프로그래밍 | NaT | True | 30000.0 |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 105215 | 1363994.0 | 670297 | 207651.0 | PAYMENT | COMPLETED | (B2B) K-Digital Credit 빅데이터 분석 첫걸음 시작하기_6기 | 프로그래밍 | B2G | 2021-09-24 16:29:55 | 30000.0 | NaN | NaN | 30000.0 | 30000.0 | INICIS | CARD | 프로그래밍 | NaT | True | 30000.0 |
| 105255 | 1364240.0 | 277200 | 207654.0 | PAYMENT | COMPLETED | (B2B) K-Digital Credit Java & SpringBoot로 시작하는... | 프로그래밍 | B2G | 2021-09-24 17:48:08 | 40000.0 | NaN | NaN | 40000.0 | 40000.0 | INICIS | CARD | 프로그래밍 | NaT | True | 40000.0 |
| 105330 | 1364604.0 | 668910 | 207652.0 | PAYMENT | COMPLETED | (B2B) K-Digital Credit 머신러닝 & AI 첫걸음 시작하기_6기 | 프로그래밍 | B2G | 2021-09-24 23:39:18 | 30000.0 | NaN | NaN | 30000.0 | 30000.0 | KAKAO | CARD | 프로그래밍 | NaT | True | 30000.0 |
| 105392 | 1364863.0 | 666665 | 207652.0 | PAYMENT | COMPLETED | (B2B) K-Digital Credit 머신러닝 & AI 첫걸음 시작하기_6기 | 프로그래밍 | B2G | 2021-09-25 11:21:54 | 30000.0 | NaN | NaN | 30000.0 | 30000.0 | INICIS | CARD | 프로그래밍 | NaT | True | 30000.0 |
| 105405 | 1364925.0 | 670842 | 207654.0 | PAYMENT | COMPLETED | (B2B) K-Digital Credit Java & SpringBoot로 시작하는... | 프로그래밍 | B2G | 2021-09-25 12:24:09 | 40000.0 | NaN | NaN | 40000.0 | 40000.0 | INICIS | CARD | 프로그래밍 | NaT | True | 40000.0 |
303 rows × 20 columns
# 온라인 완주반 테이블 추출
df_finish = pt[pt['format'].str.contains("온라인 완주반")]
df_finish
| id | customer_id | course_id | type | state | course_title | category_title | format | completed_at | transaction_amount | coupon_title | coupon_discount_amount | sale_price | tax_free_amount | pg | method | subcategory_title | marketing_start_at | purchased | revenue | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 37 | 970726.0 | 148541 | 204264.0 | PAYMENT | COMPLETED | 데이터분석 프로젝트+자격증 온라인 완주반 3기 | 데이터사이언스 | 온라인 완주반 | 2021-03-28 16:11:35 | 340000.0 | NaN | NaN | 340000.0 | 340000.0 | NaN | CARD | 데이터사이언스 | 2021-03-08 | True | 340000.0 |
| 56 | 970787.0 | 478105 | 204264.0 | PAYMENT | COMPLETED | 데이터분석 프로젝트+자격증 온라인 완주반 3기 | 데이터사이언스 | 온라인 완주반 | 2021-03-28 16:51:29 | 290000.0 | [웰컴쿠폰] 온라인 완주반 5만원 할인 쿠폰 | 50000.0 | 340000.0 | 340000.0 | NaN | CARD | 데이터사이언스 | 2021-03-08 | True | 290000.0 |
| 99 | 970962.0 | 120463 | 204266.0 | PAYMENT | COMPLETED | 컴퓨터 공학 전공자 따라잡기 온라인 완주반 3기 | 프로그래밍 | 온라인 완주반 | 2021-03-28 18:20:07 | 400000.0 | NaN | NaN | 400000.0 | 400000.0 | NaN | CARD | 프로그래밍 | 2021-01-12 | True | 400000.0 |
| 180 | 971203.0 | 478276 | 204266.0 | PAYMENT | COMPLETED | 컴퓨터 공학 전공자 따라잡기 온라인 완주반 3기 | 프로그래밍 | 온라인 완주반 | 2021-03-28 20:13:07 | 350000.0 | [웰컴쿠폰] 온라인 완주반 5만원 할인 쿠폰 | 50000.0 | 400000.0 | 400000.0 | NaN | CARD | 프로그래밍 | 2021-01-12 | True | 350000.0 |
| 183 | 971210.0 | 278861 | 204082.0 | PAYMENT | COMPLETED | 밑바닥부터 배포까지 클론코딩 온라인 완주반 1기 | 프로그래밍 | 온라인 완주반 | 2021-03-28 20:16:52 | 410000.0 | [럭키룰렛] 완주반 | 50000.0 | 460000.0 | 460000.0 | NaN | CARD | 프로그래밍 | 2021-01-28 | True | 410000.0 |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 57750 | 1153647.0 | 286143 | 205414.0 | PAYMENT | COMPLETED | 매주)SQL 100제 + 자격증 완성 온라인 완주반 | 데이터사이언스 | 온라인 완주반 | 2021-06-20 22:12:16 | 320000.0 | NaN | NaN | 320000.0 | 320000.0 | KAKAO | CARD | 데이터사이언스 | 2021-05-21 | True | 320000.0 |
| 57797 | 1153766.0 | 566216 | 203996.0 | PAYMENT | COMPLETED | 매주)디지털 마케팅 온라인 완주반 | 마케팅 | 온라인 완주반 | 2021-06-20 22:36:43 | 595000.0 | NaN | NaN | 595000.0 | 595000.0 | INICIS | CARD | 마케팅 | 2021-01-06 | True | 595000.0 |
| 57811 | 1153798.0 | 566742 | 205414.0 | PAYMENT | COMPLETED | 매주)SQL 100제 + 자격증 완성 온라인 완주반 | 데이터사이언스 | 온라인 완주반 | 2021-06-20 22:42:58 | 320000.0 | NaN | NaN | 320000.0 | 320000.0 | INICIS | CARD | 데이터사이언스 | 2021-05-21 | True | 320000.0 |
| 57904 | 1154013.0 | 554621 | 205090.0 | PAYMENT | COMPLETED | 매주) 컴퓨터 공학 전공자 따라잡기 온라인 완주반 | 프로그래밍 | 온라인 완주반 | 2021-06-20 23:18:57 | 390000.0 | NaN | NaN | 390000.0 | 390000.0 | INICIS | CARD | 프로그래밍 | 2021-04-26 | True | 390000.0 |
| 57949 | 1154116.0 | 472874 | 205204.0 | PAYMENT | COMPLETED | 매주)서비스 기획서 완성 온라인 완주반 2105 | 크리에이티브 | 온라인 완주반 | 2021-06-20 23:33:04 | 355000.0 | [50,000원] 딱 3일만! 특별 할인 쿠폰 드려요! (~6/20) | 50000.0 | 405000.0 | 405000.0 | KAKAO | POINT | 크리에이티브 | 2021-05-10 | True | 355000.0 |
1216 rows × 20 columns
# 캠프 테이블 추출
df_camp = pt[pt['format'].str.contains("캠프")]
df_camp
| id | customer_id | course_id | type | state | course_title | category_title | format | completed_at | transaction_amount | coupon_title | coupon_discount_amount | sale_price | tax_free_amount | pg | method | subcategory_title | marketing_start_at | purchased | revenue | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 2622 | 977693.0 | 99366 | 204262.0 | PAYMENT | COMPLETED | 권오상 회계사의 자금조달 분석 및 가치평가 | 부동산/금융 | 캠프 | 2021-03-30 17:52:03 | 0.0 | [무료수강권] 권오상 회계사의 자금조달 분석 및 가치평가_23기 신동현 수강생님 | 800000.0 | 800000.0 | 800000.0 | NaN | PROMOTION | 부동산/금융 | NaT | True | 0.0 |
| 8986 | 996553.0 | 224423 | 204149.0 | PAYMENT | COMPLETED | 부동산 금융 실무 : 엑셀을 활용한 부동산 사업성 분석 16기 | 부동산/금융 | 캠프 | 2021-04-07 15:03:42 | 1040000.0 | NaN | NaN | 1140000.0 | 1140000.0 | NaN | TRANSFER | 부동산/금융 | 2021-02-08 | True | 1140000.0 |
| 37817 | 1083711.0 | 448344 | 204149.0 | PAYMENT | COMPLETED | 부동산 금융 실무 : 엑셀을 활용한 부동산 사업성 분석 16기 | 부동산/금융 | 캠프 | 2021-05-20 10:33:19 | 14000.0 | NaN | NaN | 1140000.0 | 1140000.0 | NaN | TRANSFER | 부동산/금융 | 2021-02-08 | True | 1140000.0 |
| 79802 | 1242775.0 | 570092 | 206415.0 | PAYMENT | COMPLETED | Apache Spark을 이용한 빅데이터 분석 입문 15기 | 데이터사이언스 | 캠프 | 2021-07-26 11:27:39 | 1296000.0 | [추가 10% 할인] Apache Spark을 이용한 빅데이터 분석 입문 15기 | 144000.0 | 1440000.0 | 1440000.0 | INICIS | CARD | 데이터분석 | 2021-07-30 | True | 1296000.0 |
| 81606 | 1251629.0 | 11576 | 206415.0 | PAYMENT | COMPLETED | Apache Spark을 이용한 빅데이터 분석 입문 15기 | 데이터사이언스 | 캠프 | 2021-07-30 10:57:06 | 1296000.0 | [추가 10% 할인] Apache Spark을 이용한 빅데이터 분석 입문 15기 | 144000.0 | 1440000.0 | 1440000.0 | KAKAO | CARD | 데이터분석 | 2021-07-30 | True | 1296000.0 |
| 82433 | 1255884.0 | 16697 | 206415.0 | PAYMENT | COMPLETED | Apache Spark을 이용한 빅데이터 분석 입문 15기 | 데이터사이언스 | 캠프 | 2021-07-31 14:46:48 | 1296000.0 | [추가 10% 할인] Apache Spark을 이용한 빅데이터 분석 입문 15기 | 144000.0 | 1440000.0 | 1440000.0 | INICIS | CARD | 데이터분석 | 2021-07-30 | True | 1296000.0 |
| 82971 | 1257601.0 | 61727 | 206415.0 | PAYMENT | COMPLETED | Apache Spark을 이용한 빅데이터 분석 입문 15기 | 데이터사이언스 | 캠프 | 2021-07-31 23:06:15 | 1296000.0 | [추가 10% 할인] Apache Spark을 이용한 빅데이터 분석 입문 15기 | 144000.0 | 1440000.0 | 1440000.0 | INICIS | CARD | 데이터분석 | 2021-07-30 | True | 1296000.0 |
| 83731 | 1256814.0 | 509993 | 206415.0 | PAYMENT | COMPLETED | Apache Spark을 이용한 빅데이터 분석 입문 15기 | 데이터사이언스 | 캠프 | 2021-08-03 09:37:29 | 1296000.0 | [추가 10% 할인] Apache Spark을 이용한 빅데이터 분석 입문 15기 | 144000.0 | 1440000.0 | 1440000.0 | INICIS | VBANK | 데이터분석 | 2021-07-30 | True | 1296000.0 |
| 85439 | 1272544.0 | 6855 | 206415.0 | PAYMENT | COMPLETED | Apache Spark을 이용한 빅데이터 분석 입문 15기 | 데이터사이언스 | 캠프 | 2021-08-09 09:07:56 | 1440000.0 | NaN | NaN | 1440000.0 | 1440000.0 | KAKAO | CARD | 데이터분석 | 2021-07-30 | True | 1440000.0 |
| 87580 | 1281525.0 | 89024 | 206415.0 | PAYMENT | COMPLETED | Apache Spark을 이용한 빅데이터 분석 입문 15기 | 데이터사이언스 | 캠프 | 2021-08-12 18:01:08 | 1440000.0 | NaN | NaN | 1440000.0 | 1440000.0 | INICIS | CARD | 데이터분석 | 2021-07-30 | True | 1440000.0 |
| 92774 | 1304642.0 | 53748 | 206415.0 | PAYMENT | COMPLETED | Apache Spark을 이용한 빅데이터 분석 입문 15기 | 데이터사이언스 | 캠프 | 2021-08-24 16:29:08 | 1530000.0 | NaN | NaN | 1530000.0 | 1530000.0 | INICIS | CARD | 데이터분석 | 2021-07-30 | True | 1530000.0 |
| 93557 | 1308441.0 | 43623 | 206415.0 | PAYMENT | COMPLETED | Apache Spark을 이용한 빅데이터 분석 입문 15기 | 데이터사이언스 | 캠프 | 2021-08-26 18:07:27 | 830000.0 | [분할결제 쿠폰] 2 | 700000.0 | 1530000.0 | 1530000.0 | INICIS | TRANS | 데이터분석 | 2021-07-30 | True | 830000.0 |
| 93758 | 1309550.0 | 25149 | 206415.0 | PAYMENT | COMPLETED | Apache Spark을 이용한 빅데이터 분석 입문 15기 | 데이터사이언스 | 캠프 | 2021-08-27 11:09:18 | 1000000.0 | [분할결제]Apache Spark을 이용한 빅데이터 분석 입문 CAMP_100만원 | 530000.0 | 1530000.0 | 1530000.0 | INICIS | CARD | 데이터분석 | 2021-07-30 | True | 1000000.0 |
| 97077 | 1323772.0 | 277943 | 206415.0 | PAYMENT | COMPLETED | Apache Spark을 이용한 빅데이터 분석 입문 15기 | 데이터사이언스 | 캠프 | 2021-09-01 15:32:22 | 1620000.0 | NaN | NaN | 1620000.0 | 1620000.0 | KAKAO | POINT | 데이터분석 | 2021-07-30 | True | 1620000.0 |
| 99801 | 1335530.0 | 42009 | 206415.0 | PAYMENT | COMPLETED | Apache Spark을 이용한 빅데이터 분석 입문 15기 | 데이터사이언스 | 캠프 | 2021-09-08 11:07:51 | 1710000.0 | NaN | NaN | 1710000.0 | 1710000.0 | NAVER | CARD | 데이터분석 | 2021-07-30 | True | 1710000.0 |
| 100891 | 1340102.0 | 29094 | 206415.0 | PAYMENT | COMPLETED | Apache Spark을 이용한 빅데이터 분석 입문 15기 | 데이터사이언스 | 캠프 | 2021-09-10 17:22:33 | 1800000.0 | NaN | NaN | 1800000.0 | 1800000.0 | PAYCO | CARD | 데이터분석 | 2021-07-30 | True | 1800000.0 |
| 103172 | 1350583.0 | 663984 | 207532.0 | PAYMENT | COMPLETED | OpenCV로 배우는 컴퓨터 비전 프로그래밍 22기 | 프로그래밍 | 캠프 | 2021-09-16 21:24:37 | 1350000.0 | NaN | NaN | 1350000.0 | 1350000.0 | PAYCO | POINT | DevOps | 2021-09-10 | True | 1350000.0 |
# 스쿨 테이블 추출
df_school = pt[pt['format'].str.contains("스쿨")]
df_school
| id | customer_id | course_id | type | state | course_title | category_title | format | completed_at | transaction_amount | coupon_title | coupon_discount_amount | sale_price | tax_free_amount | pg | method | subcategory_title | marketing_start_at | purchased | revenue | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 2 | 970657.0 | 72297 | 204246.0 | PAYMENT | COMPLETED | 시크릿코드 : 프론트엔드 실무 완성편 | 프로그래밍 | 스쿨 온라인 | 2021-03-28 15:21:43 | 171810.0 | [10% 할인] 시크릿코드 실무 완성편 | 19090.0 | 190900.0 | 190900.0 | NaN | CARD | 프로그래밍 | 2021-03-04 | True | 171810.0 |
| 203 | 971265.0 | 175430 | 204246.0 | PAYMENT | COMPLETED | 시크릿코드 : 프론트엔드 실무 완성편 | 프로그래밍 | 스쿨 온라인 | 2021-03-28 20:39:29 | 190900.0 | NaN | NaN | 190900.0 | 190900.0 | NaN | CARD | 프로그래밍 | 2021-03-04 | True | 190900.0 |
| 293 | 971482.0 | 473334 | 204246.0 | PAYMENT | COMPLETED | 시크릿코드 : 프론트엔드 실무 완성편 | 프로그래밍 | 스쿨 온라인 | 2021-03-28 21:40:24 | 190900.0 | NaN | NaN | 190900.0 | 190900.0 | NaN | CARD | 프로그래밍 | 2021-03-04 | True | 190900.0 |
| 312 | 971527.0 | 478402 | 204246.0 | PAYMENT | COMPLETED | 시크릿코드 : 프론트엔드 실무 완성편 | 프로그래밍 | 스쿨 온라인 | 2021-03-28 21:57:31 | 190900.0 | NaN | NaN | 190900.0 | 190900.0 | NaN | CARD | 프로그래밍 | 2021-03-04 | True | 190900.0 |
| 345 | 971586.0 | 32709 | 204246.0 | PAYMENT | COMPLETED | 시크릿코드 : 프론트엔드 실무 완성편 | 프로그래밍 | 스쿨 온라인 | 2021-03-28 22:13:11 | 190900.0 | NaN | NaN | 190900.0 | 190900.0 | NaN | CARD | 프로그래밍 | 2021-03-04 | True | 190900.0 |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 93869 | 1323525.0 | 390361 | 203870.0 | PAYMENT | COMPLETED | 데이터 사이언스 취업완성 스쿨 17기 | 데이터사이언스 | 스쿨 | 2021-08-27 15:17:38 | 69211.0 | NaN | NaN | NaN | NaN | NaN | ONSITE | 데이터사이언스 | 2020-12-23 | True | 69211.0 |
| 93870 | 1323537.0 | 98171 | 203870.0 | PAYMENT | COMPLETED | 데이터 사이언스 취업완성 스쿨 17기 | 데이터사이언스 | 스쿨 | 2021-08-27 15:17:38 | 13835.0 | NaN | NaN | NaN | NaN | NaN | ONSITE | 데이터사이언스 | 2020-12-23 | True | 13835.0 |
| 93871 | 1323556.0 | 289148 | 203870.0 | PAYMENT | COMPLETED | 데이터 사이언스 취업완성 스쿨 17기 | 데이터사이언스 | 스쿨 | 2021-08-27 15:17:38 | 27669.0 | NaN | NaN | NaN | NaN | NaN | ONSITE | 데이터사이언스 | 2020-12-23 | True | 27669.0 |
| 93872 | 1323534.0 | 409454 | 203870.0 | PAYMENT | COMPLETED | 데이터 사이언스 취업완성 스쿨 17기 | 데이터사이언스 | 스쿨 | 2021-08-27 15:17:38 | 19764.0 | NaN | NaN | NaN | NaN | NaN | ONSITE | 데이터사이언스 | 2020-12-23 | True | 19764.0 |
| 93873 | 1323524.0 | 66516 | 203870.0 | PAYMENT | COMPLETED | 데이터 사이언스 취업완성 스쿨 17기 | 데이터사이언스 | 스쿨 | 2021-08-27 15:17:38 | 131832.0 | NaN | NaN | NaN | NaN | NaN | ONSITE | 데이터사이언스 | 2020-12-23 | True | 131832.0 |
415 rows × 20 columns
pt = pt.drop(list(df_b2b.index))
pt = pt.drop(list(df_b2g.index))
pt = pt.drop(list(df_finish.index))
pt = pt.drop(list(df_camp.index))
pt = pt.drop(list(df_school.index))
순 구매율
# 순 구매율
p1 = len(df[df['type']=='PAYMENT']) # 총 판매량
p2 = len(df[df['purchased']==True]) # 순 구매량
a = [p2, p1-p2] #순 구매량, 환불량
labels = ['buy'+f'\n({p2})','refund'+f'\n({p1-p2})']
wedgeprops = {'width': 0.7, 'edgecolor': 'w', 'linewidth': 3}
plt.pie(a, labels=labels, autopct='%.1f%%', wedgeprops=wedgeprops)
plt.show()
TOP 20
ctt111 = pt[['course_title','category_title']].value_counts().head(20)
# 가장 많이 구매한 강의 top 20
ctt = pt[['course_title','category_title']].value_counts().head(20)
ctt_lst = []
for i in range(20):
ctt_lst.append(pt['course_title'].value_counts(normalize=True)[i]*100)
ctt = pd.DataFrame(pt[['course_title','category_title']].value_counts().head(20))
ctt['percent'] = ctt_lst
ctt
| 0 | percent | ||
|---|---|---|---|
| course_title | category_title | ||
| 초격차 패키지 : 한 번에 끝내는 프론트엔드 개발 | 프로그래밍 | 1363 | 2.966203 |
| 초격차 패키지 : 한번에 끝내는 Java/Spring 웹 개발 마스터 | 프로그래밍 | 1357 | 2.953146 |
| 초격차 패키지 : 한번에 끝내는 영상 촬영과 편집 | 영상/3D | 1177 | 2.561424 |
| The RED : 김영하 작가의 내 안의 숨은 이야기를 찾아 쓰는 법 | 마케팅 | 1017 | 2.213227 |
| 초격차 패키지 : 한 번에 끝내는 node.js 웹 프로그래밍 | 프로그래밍 | 783 | 1.703989 |
| 나의 칼퇴치트키 엑셀유치원 | 업무생산성 | 772 | 1.680050 |
| 올인원 패키지 : star741의 캐주얼 일러스트 드로잉 | 디자인 | 648 | 1.410198 |
| 초격차 패키지 : 한 번에 끝내는 엑셀 실무 | 업무생산성 | 641 | 1.394964 |
| 초격차 패키지 : 한번에 끝내는 디자인 툴 | 디자인 | 636 | 1.384083 |
| 올인원 패키지 : 김민태의 프론트엔드 아카데미 : 제 1강 JavaScript & TypeScript Essential | 프로그래밍 | 616 | 1.340558 |
| 초격차 패키지 : 한 번에 끝내는 데이터 분석 툴 | 데이터사이언스 | 597 | 1.299210 |
| 초격차 패키지 : 한번에 끝내는 UX/UI 디자인 | 디자인 | 591 | 1.286153 |
| 초격차 패키지 : 일잘러 필수 스킬 모음.zip | 업무생산성 | 590 | 1.283976 |
| 초격차 패키지 : 30개 프로젝트로 배우는 Android 앱 개발 with Kotlin | 프로그래밍 | 583 | 1.268743 |
| 올인원 패키지 : 완전정복 시각디자인 기초 | 디자인 | 581 | 1.264390 |
| 초격차 패키지 : 한번에 끝내는 모션그래픽 | 영상/3D | 544 | 1.183870 |
| 초격차 패키지 : 한번에 끝내는 PPT 제작/디자인 | 업무생산성 | 543 | 1.181694 |
| 입만 열면 인정받는 스피치 10분컷 | 업무생산성 | 530 | 1.157755 |
| 올인원 패키지 : GA4 탑재, 구글 애널리틱스 끝장내기 | 마케팅 | 527 | 1.146874 |
| 올인원 패키지 : 디지털 마케팅 MAX 2020 | 마케팅 | 515 | 1.120759 |
# 상위 20개 강의의 구매 비율 (총 강의 개수 추가해야함)
p1 = sum(pt['course_title'].value_counts()[0:20]) # 상위 20개 구매량
p2 = sum(pt['course_title'].value_counts()[:]) # 전체 구매
a = [p1, p2-p1]
labels = ['top20'+f'\n({p1})','others'+f'\n({p2-p1})']
colors = ['silver', 'gold']
wedgeprops = {'width': 0.7, 'edgecolor': 'w', 'linewidth': 3}
plt.figure(figsize=(5,5))
plt.pie(a, labels=labels, colors=colors, autopct='%.1f%%', wedgeprops=wedgeprops)
plt.title('TOP 20 purchased rate')
plt.show()
카테고리별 분석
pt['category_title'].value_counts()
프로그래밍 14182 업무생산성 6255 데이터사이언스 6178 디자인 5397 영상/3D 4898 마케팅 4325 부동산/금융 2707 투자/재테크 1401 크리에이티브 549 지식콘텐츠 23 비즈니스 20 파이낸스 16 Name: category_title, dtype: int64
pt['category_title'].value_counts().index.tolist()
['프로그래밍', '업무생산성', '데이터사이언스', '디자인', '영상/3D', '마케팅', '부동산/금융', '투자/재테크', '크리에이티브', '지식콘텐츠', '비즈니스', '파이낸스']
# 카테고리 별 구매율
b = pt['category_title'].value_counts()
labels = ['프로그래밍','데이터사이언스','업무생산성','디자인',
'영상/3D', '마케팅', '부동산/금융', '투자/재테크', 'ETC','','','']
# 가독성 문제로 '크리에이티브','지식콘텐츠','비즈니스','파이낸스' -> ETC로 대체
wedgeprops = {'width': 0.7, 'edgecolor': 'w', 'linewidth': 1}
plt.pie(b, labels=labels, autopct='%.1f%%', wedgeprops=wedgeprops)
plt.show()
VIP 선정 기준
# id 당 구매수
t = pt.groupby("customer_id").agg({"revenue": "sum","id":'count'}).sort_values(by=["id","revenue"], ascending=False)
t
| revenue | id | |
|---|---|---|
| customer_id | ||
| 98685 | 7040750.0 | 53 |
| 50769 | 4805950.0 | 38 |
| 40783 | 4424095.0 | 34 |
| 65665 | 2958900.0 | 27 |
| 20784 | 3445050.0 | 26 |
| ... | ... | ... |
| 648707 | 0.0 | 1 |
| 651365 | 0.0 | 1 |
| 653145 | 0.0 | 1 |
| 653319 | 0.0 | 1 |
| 665031 | 0.0 | 1 |
34972 rows × 2 columns
# 상위 5% 도출
t["revenue"].sort_values(ascending=False)[:len(t)//20]
customer_id
98685 7040750.0
50769 4805950.0
40783 4424095.0
20784 3445050.0
72501 3235150.0
...
617276 376600.0
637854 376500.0
279648 376200.0
484480 376000.0
483393 376000.0
Name: revenue, Length: 1748, dtype: float64
# 40만원 이상 구매자 확인
t2 = t[(t["revenue"]>=400000)].sort_values(by=["revenue", "id"], ascending=False)
t2
| revenue | id | |
|---|---|---|
| customer_id | ||
| 98685 | 7040750.0 | 53 |
| 50769 | 4805950.0 | 38 |
| 40783 | 4424095.0 | 34 |
| 20784 | 3445050.0 | 26 |
| 72501 | 3235150.0 | 20 |
| ... | ... | ... |
| 661840 | 401000.0 | 2 |
| 526317 | 400500.0 | 4 |
| 644372 | 400500.0 | 3 |
| 457708 | 400200.0 | 4 |
| 71588 | 400000.0 | 2 |
1561 rows × 2 columns
print(f"상위 {round((len(t2)/len(t))*100, 2)}%")
상위 4.46%
# 조건을 만족하는 값들 모아 'vip' column 생성
t3 = t[(t["revenue"]>=400000)].sort_values(by=["revenue", "id"], ascending=False)
def func(x):
if x in t3.index:
return True
else:
return False
pt['vip'] = pt["customer_id"].apply(func)
# VIP 특징
t4 = pt.groupby("vip").agg({"id": "count", "revenue": "sum"})
plt.figure(figsize=(15, 5))
plt.subplot(1,3,1)
plt.pie([len(t)-len(t2), len(t2)], labels=["Normal", "VIP"], autopct='%.1f%%', startangle=260, colors=colors, counterclock=False, wedgeprops={'width': 0.7, 'edgecolor': 'w', 'linewidth': 5})
plt.xlabel("고객수 비율")
plt.subplot(1,3,2)
plt.pie(t4['id'], labels=["Normal", "VIP"], autopct='%.1f%%', startangle=260, colors=colors, counterclock=False, wedgeprops={'width': 0.7, 'edgecolor': 'w', 'linewidth': 5})
plt.xlabel("거래건수 비율")
plt.subplot(1,3,3)
plt.pie(t4['revenue'], labels=["Normal", "VIP"], autopct='%.1f%%', startangle=260, colors=colors, counterclock=False, wedgeprops={'width': 0.7, 'edgecolor': 'w', 'linewidth': 5})
plt.xlabel("수익량 비율")
plt.show()
사전 예상
카테고리: 차이가 없을 것으로 예상. -> 특정 카테고리가 vip고객에게 인기있다면 vip고객 유치 전략에 활용 가능
쿠폰 사용 : vip고객이 쿠폰을 강의 구매에 더 사용했을 것으로 예상 -> vip고객에게 높은 쿠폰 사용율이 확인되면 vip고객 확보를 위한 마케팅 목적으로 활용 가능
구매시간대 : 차이가 없을 것으로 예상. -> vip고객들이 특정 날짜 or 시간대에 강의를 구매했을 경우 특정 날짜or시간에 따른 마케팅 가능
※실제 데이터 차이가 있다고 해도 신뢰할 수 있는 데이터 분석 정보인가?
환불 : 해당 데이터셋에는 환불에 대한 단순한 수치 파악만 가능하다. 무엇 때문에 환불했는지 알 수 없음 -> 활용 불가 판단
completed_at 컬럼을 활용하여 월간 주간 일간 별로 새로운 컬럼을 만들어 구매 시간 분석에 활용
data_df = pt.copy()
data_df['completed_at']= pd.to_datetime(data_df['completed_at'])
data_df['Month'] = data_df['completed_at'].dt.month
data_df['Week'] = data_df['completed_at'].dt.week
data_df['Day'] = data_df['completed_at'].dt.day
/usr/local/lib/python3.7/dist-packages/ipykernel_launcher.py:2: FutureWarning: Series.dt.weekofyear and Series.dt.week have been deprecated. Please use Series.dt.isocalendar().week instead.
data_df.info()
<class 'pandas.core.frame.DataFrame'> Int64Index: 45951 entries, 4 to 105418 Data columns (total 24 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 id 45951 non-null float64 1 customer_id 45951 non-null int64 2 course_id 43973 non-null float64 3 type 45951 non-null object 4 state 45951 non-null object 5 course_title 45951 non-null object 6 category_title 45951 non-null object 7 format 45951 non-null object 8 completed_at 45951 non-null datetime64[ns] 9 transaction_amount 45951 non-null float64 10 coupon_title 21451 non-null object 11 coupon_discount_amount 21451 non-null float64 12 sale_price 45929 non-null float64 13 tax_free_amount 45929 non-null float64 14 pg 39400 non-null object 15 method 45951 non-null object 16 subcategory_title 45951 non-null object 17 marketing_start_at 39026 non-null datetime64[ns] 18 purchased 45951 non-null bool 19 revenue 45951 non-null float64 20 vip 45951 non-null bool 21 Month 45951 non-null int64 22 Week 45951 non-null int64 23 Day 45951 non-null int64 dtypes: bool(2), datetime64[ns](2), float64(7), int64(4), object(9) memory usage: 8.2+ MB
data_df.head()
| id | customer_id | course_id | type | state | course_title | category_title | format | completed_at | transaction_amount | ... | pg | method | subcategory_title | marketing_start_at | purchased | revenue | vip | Month | Week | Day | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 4 | 970658.0 | 478028 | 201797.0 | PAYMENT | COMPLETED | 올인원 패키지 : 직장인 필수 스킬 3종 세트 MAX | 업무생산성 | 올인원 | 2021-03-28 15:21:54 | 97500.0 | ... | NaN | CARD | PPT/보고서 | 2019-11-14 | True | 97500.0 | False | 3 | 12 | 28 |
| 8 | 970669.0 | 478033 | 203178.0 | PAYMENT | COMPLETED | 초격차 패키지 : 한번에 끝내는 영상 촬영과 편집 | 영상/3D | 올인원 | 2021-03-28 15:26:47 | 96000.0 | ... | NaN | CARD | 영상 편집 | 2020-12-02 | True | 96000.0 | False | 3 | 12 | 28 |
| 10 | 970671.0 | 469860 | 203644.0 | PAYMENT | COMPLETED | 올인원 패키지 : 권오상의 금융 아카데미 - 권오상의 재무제표 분석 기초(평생소장) | 부동산/금융 | 올인원 | 2021-03-28 15:27:17 | 263000.0 | ... | NaN | CARD | 부동산/금융 | 2020-11-27 | True | 263000.0 | False | 3 | 12 | 28 |
| 18 | 970682.0 | 478031 | NaN | PAYMENT | COMPLETED | 프로모션 : 기초부터 시작하는 데이터분석 한끝세트 (3월 프리패스) | 데이터사이언스 | 올인원 | 2021-03-28 15:33:28 | 299000.0 | ... | NaN | CARD | 데이터사이언스 | NaT | True | 299000.0 | False | 3 | 12 | 28 |
| 22 | 970695.0 | 455311 | 203146.0 | PAYMENT | COMPLETED | The RED : 현실 세상의 TDD by 이규원 | 프로그래밍 | RED | 2021-03-28 15:43:59 | 149500.0 | ... | NaN | CARD | DevOps | 2021-02-08 | True | 149500.0 | False | 3 | 12 | 28 |
5 rows × 24 columns
# VIP와 Normal고객을 각각의 테이블로 분리
vip_df = pt[pt['vip']==True]
vip_df = vip_df.sort_values(by='category_title', ascending=True)
normal_df = pt[pt['vip']==False]
normal_df = normal_df.sort_values(by='category_title', ascending=True)
#월간 구매량
plt.figure(figsize=(7, 5))
plt.rc('font', size=13)
sns.countplot(x="Month", palette='Accent',data=data_df[data_df['vip']==False])
plt.title('Normal_MONTH')
plt.show()
plt.figure(figsize=(7, 5))
plt.rc('font', size=13)
sns.countplot(x="Month", palette='Accent',data=data_df[data_df['vip']==True])
plt.title('Vip_MONTH')
plt.show()
#주간 구매량
plt.figure(figsize=(10, 5))
plt.rc('font', size=13)
sns.countplot(x="Week", palette='Accent',data=data_df[data_df['vip']==True])
plt.title('vip_Week')
plt.show()
plt.figure(figsize=(10, 5))
plt.rc('font', size=13)
sns.countplot(x="Week", palette='Accent',data=data_df[data_df['vip']==False])
plt.title('normal_Week')
plt.show()
#일간 평균 구매량
plt.figure(figsize=(10, 5))
plt.rc('font', size=13)
sns.countplot(x="Day", palette='Accent',data=data_df[data_df['vip']==True])
plt.title('vip_DAY')
plt.show()
plt.figure(figsize=(10, 5))
plt.rc('font', size=13)
sns.countplot(x="Day", palette='Accent',data=data_df[data_df['vip']==False])
plt.title('normal_DAY')
plt.show()
정리 :
plt.figure(figsize=(12, 5))
plt.rc('font', size=10)
sns.countplot(x="category_title", palette='Accent',data=vip_df)
plt.title('vip_category_title')
plt.figure(figsize=(12, 5))
plt.rc('font', size=10)
sns.countplot(x="category_title", palette='Accent',data=normal_df)
plt.title('normal_category_title')
Text(0.5, 1.0, 'normal_category_title')
#vip 인기 강의 TOP 30 (course_title)
vip_df2 = vip_df.copy()
vip_df2_ranked = vip_df2.groupby("course_title").agg({"revenue": "sum", "id": "count"}).sort_values(by='id', ascending=False)
vip_df2_ranked = vip_df2_ranked.iloc[:30,:]
vip_course_title_list = vip_df2_ranked.index
vip_df2_ranked = vip_df2_ranked.reset_index()
vip_df2_ranked
| course_title | revenue | id | |
|---|---|---|---|
| 0 | 올인원 패키지 : 권오상의 금융 아카데미 - 권오상의 재무제표 분석 심화 (수강시간... | 29674900.0 | 95 |
| 1 | 초격차 패키지 : 한 번에 끝내는 프론트엔드 개발 | 9487100.0 | 86 |
| 2 | 초격차 패키지 : 한 번에 끝내는 파이썬 웹 개발 | 9217800.0 | 85 |
| 3 | 올인원 패키지 : 권오상의 금융 아카데미 - 권오상 회계사의 자금조달 분석 및 가치... | 23071800.0 | 83 |
| 4 | 초격차 패키지 : 한 번에 끝내는 node.js 웹 프로그래밍 | 5652400.0 | 77 |
| 5 | 올인원 패키지 : 박세익 전무에게 배우는 주식 시장 분석 & 포트폴리오 운용 전략 | 21283200.0 | 75 |
| 6 | 올인원 패키지 : 김민태의 프론트엔드 아카데미 : 제 1강 JavaScript & ... | 8210200.0 | 73 |
| 7 | 초격차 패키지 : 한번에 끝내는 Java/Spring 웹 개발 마스터 | 7381600.0 | 70 |
| 8 | 초격차 패키지 : 한 번에 끝내는 AWS 인프라 구축과 DevOps 운영 | 7875200.0 | 68 |
| 9 | 올인원 패키지 : 김기현의 BERT, GPT-3를 활용한 자연어처리 | 9486000.0 | 64 |
| 10 | 올인원 패키지 : 15명의 전문 애널리스트에게 배우는 산업&매크로 분석과 투자 전략 | 18241000.0 | 64 |
| 11 | 바이블 : 파이썬 기초부터 시작하는 딥러닝 영상인식 | 6764800.0 | 63 |
| 12 | 초격차 패키지 : 한 번에 끝내는 컴퓨터 공학 전공필수 & 인공지능 심화 | 11148000.0 | 61 |
| 13 | 초격차 패키지 : 30개 프로젝트로 배우는 Android 앱 개발 with Kotlin | 6547500.0 | 57 |
| 14 | 초격차 패키지 : 한 번에 끝내는 데이터 분석 | 5197400.0 | 57 |
| 15 | 올인원 패키지 : 권오상의 금융 아카데미 - 권오상의 재무제표 분석 기초 (수강시간... | 14680000.0 | 56 |
| 16 | 초격차 패키지 : 한번에 끝내는 UX/UI 디자인 | 7577500.0 | 53 |
| 17 | 올인원 패키지 : 완전정복 시각디자인 기초 | 8137500.0 | 53 |
| 18 | 초격차 패키지 : 한 번에 끝내는 딥러닝/인공지능 | 8905950.0 | 50 |
| 19 | 초격차 패키지 : 한번에 끝내는 디자인 툴 | 7713200.0 | 49 |
| 20 | 올인원 패키지 : 100억을 움직이는 단 10장의 PPT | 5835000.0 | 49 |
| 21 | 초격차 패키지 : 한번에 끝내는 영상 촬영과 편집 | 4553500.0 | 49 |
| 22 | 올인원 패키지 : 박민수에게 배우는 직장인 초현실 투자 전략 | 9767000.0 | 47 |
| 23 | 올인원 패키지 : 강필성의 머신러닝 아카데미 | 6105950.0 | 47 |
| 24 | 초격차 패키지 : 한번에 끝내는 금융ㆍ투자(IB) 실무 | 11516000.0 | 46 |
| 25 | 초격차 패키지 : 한 번에 끝내는 데이터 분석 툴 | 3580450.0 | 46 |
| 26 | 연습문제 패키지 : 퀴즈처럼 풀면서 배우는 파이썬 딥러닝 300제+ | 4314500.0 | 45 |
| 27 | (프로모션 7/16-7/29) 초격차 패키지 : 한 번에 끝내는 Spring 완.전.판 | 6212900.0 | 45 |
| 28 | 초격차 패키지 : 일잘러 필수 스킬 모음.zip | 4816000.0 | 43 |
| 29 | 초격차 패키지 : 한 번에 끝내는 코딩테스트 369 Java편 | 3567200.0 | 43 |
#Normal 인기 강의 TOP 30 (couse_title)
normal_df2 = normal_df.copy()
normal_df2_ranked = normal_df2.groupby("course_title").agg({"revenue": "sum", "id": "count"}).sort_values(by='id', ascending=False)
normal_df2_ranked = normal_df2_ranked.iloc[:30,:]
normal_course_title_list = normal_df2_ranked.index
normal_df2_ranked = normal_df2_ranked.reset_index()
normal_df2_ranked
| course_title | revenue | id | |
|---|---|---|---|
| 0 | 초격차 패키지 : 한번에 끝내는 Java/Spring 웹 개발 마스터 | 107043025.0 | 1287 |
| 1 | 초격차 패키지 : 한 번에 끝내는 프론트엔드 개발 | 139089300.0 | 1277 |
| 2 | 초격차 패키지 : 한번에 끝내는 영상 촬영과 편집 | 115279500.0 | 1128 |
| 3 | The RED : 김영하 작가의 내 안의 숨은 이야기를 찾아 쓰는 법 | 150255500.0 | 992 |
| 4 | 나의 칼퇴치트키 엑셀유치원 | 85842000.0 | 735 |
| 5 | 초격차 패키지 : 한 번에 끝내는 node.js 웹 프로그래밍 | 34547100.0 | 706 |
| 6 | 올인원 패키지 : star741의 캐주얼 일러스트 드로잉 | 85028200.0 | 619 |
| 7 | 초격차 패키지 : 한 번에 끝내는 엑셀 실무 | 52743800.0 | 605 |
| 8 | 초격차 패키지 : 한번에 끝내는 디자인 툴 | 83844400.0 | 587 |
| 9 | 초격차 패키지 : 한 번에 끝내는 데이터 분석 툴 | 42591550.0 | 551 |
| 10 | 초격차 패키지 : 일잘러 필수 스킬 모음.zip | 58755900.0 | 547 |
| 11 | 올인원 패키지 : 김민태의 프론트엔드 아카데미 : 제 1강 JavaScript & ... | 57965100.0 | 543 |
| 12 | 초격차 패키지 : 한번에 끝내는 UX/UI 디자인 | 77021800.0 | 538 |
| 13 | 올인원 패키지 : 완전정복 시각디자인 기초 | 76961300.0 | 528 |
| 14 | 초격차 패키지 : 30개 프로젝트로 배우는 Android 앱 개발 with Kotlin | 57971500.0 | 526 |
| 15 | 입만 열면 인정받는 스피치 10분컷 | 10559600.0 | 513 |
| 16 | 초격차 패키지 : 한번에 끝내는 모션그래픽 | 66726250.0 | 505 |
| 17 | 초격차 패키지 : 한번에 끝내는 PPT 제작/디자인 | 44444400.0 | 502 |
| 18 | 올인원 패키지 : GA4 탑재, 구글 애널리틱스 끝장내기 | 47916500.0 | 499 |
| 19 | 올인원 패키지 : 디지털 마케팅 MAX 2020 | 58660525.0 | 499 |
| 20 | 합격 패스 : 정보처리기사 필기&실기 | 2912415.0 | 471 |
| 21 | 올인원 패키지 : 알고리즘 기술면접 완전 정복 | 42814300.0 | 471 |
| 22 | 올인원 패키지 : 컴퓨터 공학 전공 필수 | 50236975.0 | 452 |
| 23 | 올인원 패키지 : 아카데미 : 편집하는여자의 영상편집 마스터클래스 - 제 1강 프리... | 41638000.0 | 450 |
| 24 | 초격차 패키지 : 한 번에 끝내는 코딩테스트 369 Java편 | 42161250.0 | 445 |
| 25 | 올인원 패키지 : 박세익 전무에게 배우는 주식 시장 분석 & 포트폴리오 운용 전략 | 114257000.0 | 398 |
| 26 | 올인원 패키지 : 디자이너 몰래 듣는 압축 포토샵 | 28075920.0 | 386 |
| 27 | 올인원 패키지 : 직장인을 위한 파이썬 데이터분석 | 41150400.0 | 382 |
| 28 | 초격차 패키지 : 한 번에 끝내는 파이썬 웹 개발 | 42328100.0 | 376 |
| 29 | 용호수의 돈 버는 실전 영상 제작 | 56459000.0 | 369 |
intersection_course_title = normal_course_title_list & vip_course_title_list
print('중복되는 강좌의 수 : ',len(intersection_course_title),'개')
print(intersection_course_title)
중복되는 강좌의 수 : 14 개
Index(['초격차 패키지 : 한번에 끝내는 Java/Spring 웹 개발 마스터', '초격차 패키지 : 한 번에 끝내는 프론트엔드 개발',
'초격차 패키지 : 한번에 끝내는 영상 촬영과 편집', '초격차 패키지 : 한 번에 끝내는 node.js 웹 프로그래밍',
'초격차 패키지 : 한번에 끝내는 디자인 툴', '초격차 패키지 : 한 번에 끝내는 데이터 분석 툴',
'초격차 패키지 : 일잘러 필수 스킬 모음.zip',
'올인원 패키지 : 김민태의 프론트엔드 아카데미 : 제 1강 JavaScript & TypeScript Essential',
'초격차 패키지 : 한번에 끝내는 UX/UI 디자인', '올인원 패키지 : 완전정복 시각디자인 기초',
'초격차 패키지 : 30개 프로젝트로 배우는 Android 앱 개발 with Kotlin',
'초격차 패키지 : 한 번에 끝내는 코딩테스트 369 Java편',
'올인원 패키지 : 박세익 전무에게 배우는 주식 시장 분석 & 포트폴리오 운용 전략',
'초격차 패키지 : 한 번에 끝내는 파이썬 웹 개발'],
dtype='object', name='course_title')
/usr/local/lib/python3.7/dist-packages/ipykernel_launcher.py:1: FutureWarning: Index.__and__ operating as a set operation is deprecated, in the future this will be a logical operation matching Series.__and__. Use index.intersection(other) instead """Entry point for launching an IPython kernel.
서로 중복되는 카테고리와 강의명
| Categories | course_name |
|---|---|
| 프로그래밍 | 초격차 패키지 : 한번에 끝내는 Java/Spring 웹 개발 마스터 |
| 프로그래밍 | 초격차 패키지 : 한 번에 끝내는 프론트엔드 개발 |
| 프로그래밍 | 초격차 패키지 : 한 번에 끝내는 파이썬 웹 개발 |
| 프로그래밍 | 초격차 패키지 : 한 번에 끝내는 node.js 웹 프로그래밍 |
| 프로그래밍 | 초격차 패키지 : 30개 프로젝트로 배우는 Android 앱 개발 with Kotlin |
| 프로그래밍 | 올인원 패키지 : 김민태의 프론트엔드 아카데미 : 제 1강 JavaScript & TypeScript Essential |
| 디자인 | 초격차 패키지 : 한번에 끝내는 UX/UI 디자인 |
| 디자인 | 올인원 패키지 : 완전정복 시각디자인 기초 |
| 데이터사이언스 | 초격차 패키지 : 한 번에 끝내는 데이터 분석 툴 |
| 업무생산성 | 초격차 패키지 : 일잘러 필수 스킬 모음.zip |
| 투자/재테크 | 올인원 패키지 : 박세익 전무에게 배우는 주식 시장 분석 & 포트폴리오 운용 전략 |
| 영상/3D | 초격차 패키지 : 한번에 끝내는 영상 촬영과 편집 |
결과
vip_df.info()
<class 'pandas.core.frame.DataFrame'> Int64Index: 5872 entries, 105406 to 69871 Data columns (total 21 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 id 5872 non-null float64 1 customer_id 5872 non-null int64 2 course_id 5220 non-null float64 3 type 5872 non-null object 4 state 5872 non-null object 5 course_title 5872 non-null object 6 category_title 5872 non-null object 7 format 5872 non-null object 8 completed_at 5872 non-null datetime64[ns] 9 transaction_amount 5872 non-null float64 10 coupon_title 2030 non-null object 11 coupon_discount_amount 2030 non-null float64 12 sale_price 5870 non-null float64 13 tax_free_amount 5870 non-null float64 14 pg 5274 non-null object 15 method 5872 non-null object 16 subcategory_title 5872 non-null object 17 marketing_start_at 4691 non-null datetime64[ns] 18 purchased 5872 non-null bool 19 revenue 5872 non-null float64 20 vip 5872 non-null bool dtypes: bool(2), datetime64[ns](2), float64(7), int64(1), object(9) memory usage: 1.0+ MB
vip_df['coupon_title'].notnull().sum()
2030
vip_df['coupon_title'].isnull().sum()
3842
#쿠폰 사용율
#전체인원수 / 쿠폰 사용자 수
ratio = [len(vip_df), vip_df['coupon_title'].notnull().sum()]
labels = ["VIP's_not_used_coupon_ratio", "VIP's_used_coupon_ratio"]
plt.figure(figsize=(7, 5))
plt.rc('font', size=11)
plt.pie(ratio, labels=labels, autopct='%.0f%%', startangle=130, counterclock=False)
plt.show()
ratio2 = [len(normal_df), normal_df['coupon_title'].notnull().sum()]
labels2 = ["Normal's_not_used_coupon_ratio", "Normal's_used_coupon_ratio"]
plt.figure(figsize=(7, 5))
plt.rc('font', size=11)
plt.pie(ratio2, labels=labels2, autopct='%.0f%%', startangle=120, counterclock=False)
plt.show()
#1인당 쿠폰 사용 금액
#총 쿠폰 사용 금액 / 쿠폰 사용자 수
x = [1,2]
years = ['vip', 'normal']
values = [(vip_df['coupon_discount_amount'].sum() / vip_df['coupon_title'].notnull().sum()) , (normal_df['coupon_discount_amount'].sum() / normal_df['coupon_title'].notnull().sum()) ]
plt.bar(x, values)
plt.xticks(x, years)
plt.text(0.77,40000, (round(vip_df['coupon_discount_amount'].sum() / vip_df['coupon_title'].notnull().sum()),'원'))
plt.text(1.78,30000, (round(normal_df['coupon_discount_amount'].sum() / normal_df['coupon_title'].notnull().sum()),'원'))
plt.show()
ratio2 = [round(vip_df['coupon_discount_amount'].sum() / vip_df['coupon_title'].notnull().sum()), round(normal_df['coupon_discount_amount'].sum() / normal_df['coupon_title'].notnull().sum())]
labels2 = ["Vip's average coupon cost", "Normal's average coupon cost"]
plt.figure(figsize=(9, 5))
plt.rc('font', size=13)
plt.pie(ratio2, labels=labels2, autopct='%.0f%%', startangle=-80, counterclock=False)
plt.show()
#전체 대상, 가장 많이 사용된 쿠폰 종류
df_coupon = df.groupby("coupon_title").agg({ "id": "count"}).sort_values(by='id', ascending=False)
df_coupon = df_coupon.reset_index()
df_coupon.head(10)
| coupon_title | id | |
|---|---|---|
| 0 | [웰컴쿠폰] 올인원 패키지 2만원 할인 쿠폰 | 5498 |
| 1 | [WELCOME] 온라인 강의 3만원 할인쿠폰 | 3206 |
| 2 | [웰컴쿠폰] 올인원 패키지 1만원 할인 쿠폰 | 2469 |
| 3 | [WELCOME] 온라인 강의 2만원 할인쿠폰 | 2325 |
| 4 | [WELCOME] 온라인 강의 1만원 할인쿠폰 | 1900 |
| 5 | 8월 1+1 프로모션 쿠폰 | 1458 |
| 6 | 4월 1+1 페이백 이벤트 쿠폰 | 1350 |
| 7 | [웰컴쿠폰] 올인원 패키지 3만원 할인 쿠폰 | 1284 |
| 8 | [미래투자금] 온라인 강의 2만원 할인쿠폰 | 1274 |
| 9 | 5월 페이백 프로모션 쿠폰 | 1126 |
#VIP대상, 가장 많이 사용된 쿠폰 종류
vip_coupon = vip_df.groupby("coupon_title").agg({ "id": "count"}).sort_values(by='id', ascending=False)
vip_coupon = vip_coupon.reset_index()
vip_coupon.head(10)
| coupon_title | id | |
|---|---|---|
| 0 | 8월 1+1 프로모션 쿠폰 | 230 |
| 1 | 7월 100% 페이백 프로모션 쿠폰 | 141 |
| 2 | [WELCOME] 온라인 강의 1만원 할인쿠폰 | 129 |
| 3 | [웰컴쿠폰] 올인원 패키지 1만원 할인 쿠폰 | 129 |
| 4 | 5월 페이백 프로모션 쿠폰 | 123 |
| 5 | [웰컴쿠폰] 올인원 패키지 2만원 할인 쿠폰 | 118 |
| 6 | 4월 1+1 페이백 이벤트 쿠폰 | 117 |
| 7 | [WELCOME] 온라인 강의 2만원 할인쿠폰 | 68 |
| 8 | [WELCOME] 온라인 강의 3만원 할인쿠폰 | 66 |
| 9 | [웰컴쿠폰] 올인원 패키지 3만원 할인 쿠폰 | 55 |
#Normal대상, 가장 많이 사용된 쿠폰 종류
normal_coupon = normal_df.groupby("coupon_title").agg({ "id": "count"}).sort_values(by='id', ascending=False)
normal_coupon = normal_coupon.reset_index()
normal_coupon.head(10)
| coupon_title | id | |
|---|---|---|
| 0 | [웰컴쿠폰] 올인원 패키지 2만원 할인 쿠폰 | 3562 |
| 1 | [WELCOME] 온라인 강의 3만원 할인쿠폰 | 1972 |
| 2 | [웰컴쿠폰] 올인원 패키지 1만원 할인 쿠폰 | 1577 |
| 3 | [WELCOME] 온라인 강의 2만원 할인쿠폰 | 1513 |
| 4 | [WELCOME] 온라인 강의 1만원 할인쿠폰 | 1153 |
| 5 | 4월 1+1 페이백 이벤트 쿠폰 | 1042 |
| 6 | 8월 1+1 프로모션 쿠폰 | 1024 |
| 7 | 5월 페이백 프로모션 쿠폰 | 850 |
| 8 | [미래투자금] 온라인 강의 2만원 할인쿠폰 | 788 |
| 9 | 7월 100% 페이백 프로모션 쿠폰 | 787 |
정리
쿠폰 사용량은 vip 고객과 normal 고객의 각각 28%, 32%로 30% 전 후 양상을 보이며 서로 큰 차이가 없어보인다.
1인 쿠폰 사용금액량에서는 vip고객이 약68,000원 normal 고객이 약 51,000원으로 vip고객이 normal 고객에 비해 30% 높은 결과가 나타났다.
vip 고객이 가장 많이 사용한 쿠폰의 종류는 프로모션 쿠폰과 금액 할인권이 있다. 전반적으로 한쪽에 크게 치우지지 않는 경향을 보인다.
normal 고객이 사용한 쿠폰의 종류에서 1위~5위의 금액 할인권이 전체의48%를 차지할 정도로 압도적으로 많다.
vip에 근접한 타겟 분석
근접 타겟 분석
tt1 = pt.groupby("customer_id").agg({"revenue": "sum","id":'count'}).sort_values(by=["revenue", "id"], ascending=False)
# 조건을 만족하는 값들 모아 'pre_vip' column 생성, target 지정
tt2 = t[(t['revenue']>=300000)&(t['revenue']<400000)].sort_values(by=["revenue", "id"], ascending=False)
def func(x):
if x in tt2.index:
return True
else:
return False
pt['pre_vip'] = pt["customer_id"].apply(func)
target = pt[pt['pre_vip']==True]
# 전체 비율의 약 4.9%
plt.figure(figsize=(5, 5))
colors = ['green','gold','silver']
plt.pie([len(t2),len(tt2), len(t)-len(tt2)-len(t2)], labels=["VIP","target", "total users"], autopct='%.1f%%', startangle=260, colors=colors, counterclock=False, wedgeprops={'width': 0.7, 'edgecolor': 'w', 'linewidth': 5})
plt.show()
# 전체적인 카테고리별 판매량과 유사한 패턴을 가짐
ttt = target['category_title'].value_counts()
plt.figure(figsize=(5, 5))
a = ['프로그래밍','데이터사이언스','투자/재테크','업무생산성','디자인','부동산/금융',
'영상/3D','마케팅','크리에이티브','ETC','',''] # 가독성을 위해 '비즈니스','파이낸스','지식콘텐츠' -> ETC로 대체
wedgeprops = {'width': 0.7, 'edgecolor': 'w', 'linewidth': 2}
plt.pie(ttt, labels=a, autopct='%.1f%%', wedgeprops=wedgeprops)
plt.show()
# 세부 카테고리 조사, 조사를 위해 새로운 column 생성
aaaa = target.groupby("subcategory_title").agg({"id": "count"}).sort_values(by='id', ascending=False)
aaaa["target_category"] = ""
aaaa["target_category"][:10] = target["subcategory_title"].value_counts()[:10].index.to_list()
aaaa["target_category"][10:] = "etc"
/usr/local/lib/python3.7/dist-packages/ipykernel_launcher.py:4: SettingWithCopyWarning: A value is trying to be set on a copy of a slice from a DataFrame See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy after removing the cwd from sys.path. /usr/local/lib/python3.7/dist-packages/ipykernel_launcher.py:5: SettingWithCopyWarning: A value is trying to be set on a copy of a slice from a DataFrame See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy """
# TOP10 세부 카테고리를 추리기 위해 다시 그룹 만듦
a2222 = aaaa.groupby("target_category").agg({"id": "sum"}).sort_values(by='id', ascending=False)
# 세부 카테고리 TOP10, 단일 비율은 주식 투자, 크리에이티브가 가장 높음
plt.figure(figsize=(5, 5))
# TOP 10 외 항목은 ETC로 대체
wedgeprops = {'width': 0.7, 'edgecolor': 'w', 'linewidth': 2}
plt.pie(a2222["id"],labels=a2222.index,autopct='%.1f%%', wedgeprops=wedgeprops)
plt.show()
# 가장 많이 들은 강좌 TOP 10
target['course_title'].value_counts().head(10)
올인원 패키지 : 박세익 전무에게 배우는 주식 시장 분석 & 포트폴리오 운용 전략 236 초격차 패키지 : 한 번에 끝내는 프론트엔드 개발 72 올인원 패키지 : 권오상의 금융 아카데미 - 권오상의 재무제표 분석 심화 (수강시간 제한) 71 초격차 패키지 : 한번에 끝내는 Java/Spring 웹 개발 마스터 65 올인원 패키지 : 15명의 전문 애널리스트에게 배우는 산업&매크로 분석과 투자 전략 65 올인원 패키지 : 권오상의 금융 아카데미 - 권오상 회계사의 자금조달 분석 및 가치평가 (수강시간 제한) 54 올인원 패키지 : 완전정복 시각디자인 기초 52 초격차 패키지 : 일잘러 필수 스킬 모음.zip 44 초격차 패키지 : 한 번에 끝내는 파이썬 웹 개발 42 초격차 패키지 : 한 번에 끝내는 node.js 웹 프로그래밍 41 Name: course_title, dtype: int64
# target의 평균 소비 금액
# 평균적으로 33.7만원 정도 소비
target['revenue'].sum()/target['customer_id'].nunique()
337475.1437793427
# 강의 한 개당 평균 가격은 29.5만원 선
target['sale_price'].sum()/target['course_id'].nunique()
2956612.727272727
# 타겟 유저들의 평균 강의 수강 수
print(f"purchased_counts: \n{target['customer_id'].value_counts()}")
print('')
print(f"user_counts: {target['customer_id'].nunique()}")
print('')
print(f"lecture_counts_rate: {len(target)/target['customer_id'].nunique()}")
purchased_counts:
495383 7
515059 7
279483 7
494310 6
444486 6
..
624029 1
77604 1
623774 1
538391 1
12719 1
Name: customer_id, Length: 1704, dtype: int64
user_counts: 1704
lecture_counts_rate: 2.0252347417840375
target['coupon_title'].value_counts()
[웰컴쿠폰] 올인원 패키지 2만원 할인 쿠폰 121
8월 1+1 프로모션 쿠폰 111
[WELCOME] 온라인 강의 1만원 할인쿠폰 105
[미래투자금] 온라인 강의 2만원 할인쿠폰 83
[WELCOME] 온라인 강의 3만원 할인쿠폰 82
...
[재결제쿠폰]올인원 패키지 : 딥러닝을 활용한 추천시스템 구현 1
[할인쿠폰] 재테크 카테고리 AOP 30% 할인 (금융 아카데미 제외) 1
[시크릿쿠폰] 산돌 런칭기념 30% 할인쿠폰 1
[할인 쿠폰] 게임 개발자 취업의 모든 것 20% 할인 1
[20%할인] The RED : Hadoop & Spark 아키텍처 딥다이브 1
Name: coupon_title, Length: 99, dtype: int64
# 쿠폰 사용 여부
# 66% 정도가 쿠폰을 써서 결제한 사실을 알 수 있다.
print(f"coupon_used : {target['coupon_title'].isna().sum()}")
print(f"used_rate : {(target['coupon_title'].isna().sum())/len(target)*100}%")
coupon_used : 2295 used_rate : 66.50246305418719%
# 쿠폰 할인 비율
# 11.6% 정도 할인 받은 사실을 알 수 있다.
print(f"purchased_amount: {target['revenue'].sum()}")
print(f"coupon_discount_amount: {target['coupon_discount_amount'].sum()}")
print(f"coupon_discount_amount_rate: {target['coupon_discount_amount'].sum()/target['revenue'].sum()*100}%")
purchased_amount: 575057645.0 coupon_discount_amount: 66696855.0 coupon_discount_amount_rate: 11.598290289663048%
# 타겟들의 결제 방식
print(target['pg'].value_counts())
print()
print(target['method'].value_counts())
INICIS 2024 KAKAO 578 NAVER 396 PAYCO 141 CHAI 3 Name: pg, dtype: int64 CARD 2569 POINT 474 VBANK 189 PROMOTION 105 TRANSFER 67 TRANS 45 ONSITE 2 Name: method, dtype: int64
정리
plt.figure(figsize=(12,5))
sns.countplot(x=pt[pt['vip']==False]['format'],data=pt)
plt.show()
# vip 아닌 고객들의 category 조사
all_cnt = pt[(pt['vip']==False)&(pt['format']=='올인원')]['category_title']
plt.figure(figsize=(17,5))
plt.xticks(rotation = 15)
sns.countplot(x=all_cnt,data=pt)
<matplotlib.axes._subplots.AxesSubplot at 0x7f1762bff9d0>
sub_cnt = pt[(pt['vip']==False)&(pt['format']=='올인원')&(pt['category_title']=='프로그래밍')]['subcategory_title']
plt.figure(figsize=(17,5))
plt.xticks(rotation = 15)
sns.countplot(x=sub_cnt,data=pt)
<matplotlib.axes._subplots.AxesSubplot at 0x7f1763c81250>
# 날짜를 일 단위까지 정리하기.
def func(x):
return x.strftime("%Y-%m-%d")
pt["completed_at"] = pt["completed_at"].apply(func)
plt.figure(figsize=(30,6))
plt.xticks(size=8, rotation = 90)
sns.countplot(x=pt[pt['vip']==False]['completed_at'],data=pt)
<matplotlib.axes._subplots.AxesSubplot at 0x7f17640cd850>
plt.figure(figsize=(30,6))
plt.xticks(size=5, rotation = 90)
sns.countplot(x=pt[pt['vip']==False]['coupon_title'],data=pt)
plt.show()
x= [] # 날짜
y= [] # 총 구매량
y1= [] # 쿠폰사용 구매량
for i in range(3,9):
if i%2 ==0:
x.append(f'{i}월30일')
y.append(len(pt[(pt['vip']==False)&(pt['completed_at']==f'2021-0{i}-30')]))
y1.append(len(pt[(pt['vip']==False)&(pt['completed_at']==f'2021-0{i}-30')].dropna(subset=['coupon_title'])))
else:
x.append(f'{i}월31일')
y.append(len(pt[(pt['vip']==False)&(pt['completed_at']==f'2021-0{i}-31')]))
y1.append(len(pt[(pt['vip']==False)&(pt['completed_at']==f'2021-0{i}-31')].dropna(subset=['coupon_title'])))
bar1 = plt.bar(x,y, label= "전체")
bar2 = plt.bar(x,y1, label= "쿠폰 사용")
plt.xticks(rotation=60)
plt.legend()
for idx, rect in enumerate(bar1):
plt.text(idx, rect.get_height()+ 0.5,y[idx], ha= 'center', color= 'blue')
for idx, rect in enumerate(bar2):
plt.text(idx, rect.get_height()+ 0.5,y1[idx], ha= 'center', color= 'red')
plt.figure(figsize=(70,5))
for i in range(3,9):
plt.subplot(1,7,i-2)
plt.xticks(size=10, rotation = 90)
plt.title(f'{i}월')
if i%2 == 0:
sns.countplot(x=pt[(pt['vip']==False)&(pt['completed_at']==f'2021-0{i}-30')]['coupon_title'],data=pt[(pt['vip']==False)&(pt['completed_at']==f'2021-0{i}-30')])
else:
sns.countplot(x=pt[(pt['vip']==False)&(pt['completed_at']==f'2021-0{i}-31')]['coupon_title'],data=pt[(pt['vip']==False)&(pt['completed_at']==f'2021-0{i}-31')])
# 결제 데이터 달단위 분석.(따로 카피데이터 사용)
import copy
mon = copy.copy(pt)
def func_m(x):
return x[:7]
mon["completed_at"] = mon["completed_at"].apply(func_m)
# 3월 전체, 9월 말 (25일 이후) 데이터는 특정 구간이 생략되어 있음, 해석 시 주의 요망
plt.figure(figsize=(10,5))
sns.countplot(x=mon[mon['vip']==False]['completed_at'],data=mon)
plt.show()
# 매월 쿠폰사용
plt.figure(figsize=(110,5))
for i in range(3,9):
plt.subplot(1,7,i-2)
plt.xticks(rotation = 90)
plt.title(f'{i}월')
sns.countplot(x=mon[(mon['vip']==False)&(mon['completed_at']==f'2021-0{i}')]['coupon_title'],data=mon[(mon['vip']==False)&(mon['completed_at']==f'2021-0{i}')])
x_m= [] # 날짜
y_m= [] # 총 구매량
y1_m= [] # 쿠폰사용 구매량
for i in range(3,9):
x_m.append(f'{i}월')
y_m.append(len(mon[(mon['vip']==False)&(mon['completed_at']==f'2021-0{i}')]))
y1_m.append(len(mon[(mon['vip']==False)&(mon['completed_at']==f'2021-0{i}')].dropna(subset=['coupon_title'])))
bar3 = plt.bar(x_m,y_m, label= "전체")
bar4 = plt.bar(x_m,y1_m, label= "쿠폰 사용")
plt.xticks(rotation=60)
for idx, rect in enumerate(bar3):
plt.text(idx, rect.get_height()+ 0.5,y_m[idx], ha= 'center', color= 'blue')
for idx, rect in enumerate(bar4):
plt.text(idx, rect.get_height()+ 0.5,y1_m[idx], ha= 'center', color= 'red')
pt[(pt['vip']==False)&(pt['format']=='올인원')]['subcategory_title']
plt.figure(figsize=(20,5))
plt.xticks(rotation = 90)
sns.countplot(x=pt[(pt['vip']==False)&(pt['format']=='올인원')]['subcategory_title'],data=pt)
plt.show()
plt.figure(figsize=(100,5))
plt.xticks(rotation = 90)
sns.countplot(x=pt[(pt['vip']==False)&(pt['format']=='올인원')]['course_title'],data=pt)
plt.show()
pt[(pt['vip']==False)&(pt['format']=='올인원')]['revenue'].mean()
117603.12643550932
vip가 아닌 고객들이 구매한 Top 3 강의명을 기준으로 평균가격 -> 신규고객 또는 기존고객이 강의를 구매할 때 부담이 없을 것이라 판단
# 영상 촬영 편집 강의의 평균구매가격
a= int(pt[(pt['vip']==False)&(pt['format']=='올인원')&(pt['course_title']=='초격차 패키지 : 한번에 끝내는 영상 촬영과 편집')]['revenue'].mean())
# 프론트엔드 강의의 평균구매가격
b= int(pt[(pt['vip']==False)&(pt['format']=='올인원')&(pt['course_title']=="초격차 패키지 : 한 번에 끝내는 프론트엔드 개발")]['revenue'].mean())
# 웹 개발 강의의 평균구매가격
c= int(pt[(pt['vip']==False)&(pt['format']=='올인원')&(pt['course_title']=='초격차 패키지 : 한번에 끝내는 Java/Spring 웹 개발 마스터')]['revenue'].mean())
print('올인원 Top 3 강의 평균 구매가격:',(a+b+c)/3,'원')
올인원 Top 3 강의 평균 구매가격: 98096.0 원
21년 9월 이후로 위와 같은 인기있는 강의의 카테고리와 가격대를 형성하여 판매한다면 신규고객과 기존고객의 유치하기에 적합해 보임
올인원 타이틀을 앞세워 강의를 판매하는 전략이 유효하다.
쿠폰 사용에 따른 분석
pt.loc[pt['vip']==True,'vip'] = "VIP"
pt.loc[pt['vip']==False,'vip'] = "Normal"
t = pt[~pt["coupon_title"].isnull()]
t2 = pt[pt["coupon_title"].isnull()]
plt.figure(figsize=(10, 10))
colors = sns.color_palette('Set2')[0:8]
t3 = t.groupby("vip").agg({"id": "count", "revenue": "sum"})
plt.subplot(2,2,1)
plt.title("쿠폰O 구매비율")
plt.pie(t3['id'], labels=t3.index, autopct='%.1f%%', startangle=260, colors=colors, counterclock=False, wedgeprops={'width': 0.7, 'edgecolor': 'w', 'linewidth': 5})
plt.xlabel(f"총 {t3['id'].sum()} 건")
plt.subplot(2,2,2)
plt.title("쿠폰O 수익비율")
plt.pie(t3['revenue'], labels=t3.index, autopct='%.1f%%', startangle=260, colors=colors, counterclock=False, wedgeprops={'width': 0.7, 'edgecolor': 'w', 'linewidth': 5})
plt.xlabel(f"총 {t3['revenue'].astype(int).sum():,}원")
t3 = t2.groupby("vip").agg({"id": "count", "revenue": "sum"})
plt.subplot(2,2,3)
plt.title("쿠폰X 구매비율")
plt.pie(t3['id'], labels=t3.index, autopct='%.1f%%', startangle=260, colors=colors, counterclock=False, wedgeprops={'width': 0.7, 'edgecolor': 'w', 'linewidth': 5})
plt.xlabel(f"총 {t3['id'].sum()} 건")
plt.subplot(2,2,4)
plt.title("쿠폰X 수익비율")
plt.pie(t3['revenue'], labels=t3.index, autopct='%.1f%%', startangle=260, colors=colors, counterclock=False, wedgeprops={'width': 0.7, 'edgecolor': 'w', 'linewidth': 5})
plt.xlabel(f"총 {t3['revenue'].astype(int).sum():,}원")
plt.show()
t = pt[pt["coupon_title"].isnull() & (pt["vip"]=='Normal')]
t2 = t.groupby("category_title").agg({"id": "count", "revenue": "sum"})
t2.drop(["비즈니스", "지식콘텐츠", "파이낸스"], inplace=True) # 비즈니스 15건, 지식콘텐츠 14건, 파이낸스 12건
t2
| id | revenue | |
|---|---|---|
| category_title | ||
| 데이터사이언스 | 2662 | 416284900.0 |
| 디자인 | 2026 | 307387700.0 |
| 마케팅 | 2610 | 370433400.0 |
| 부동산/금융 | 1148 | 230437500.0 |
| 업무생산성 | 3393 | 302852700.0 |
| 영상/3D | 1906 | 273969600.0 |
| 크리에이티브 | 376 | 95799400.0 |
| 투자/재테크 | 407 | 105265500.0 |
| 프로그래밍 | 6095 | 825216700.0 |
plt.figure(figsize=(12, 6))
colors = sns.color_palette('Set2')[0:8]
plt.subplot(1,2,1)
plt.pie(t2['id'], labels=t2.index, autopct='%.1f%%', startangle=260, colors=colors, counterclock=False, wedgeprops={'width': 0.7, 'edgecolor': 'w', 'linewidth': 5})
plt.xlabel(f"거래건수 비율\n 총 {t2['id'].sum()} 건")
plt.subplot(1,2,2)
plt.pie(t2['revenue'], labels=t2.index, autopct='%.1f%%', startangle=260, colors=colors, counterclock=False, wedgeprops={'width': 0.7, 'edgecolor': 'w', 'linewidth': 5})
plt.xlabel(f"수익률 비율\n 총 {t2['revenue'].astype(int).sum():,}원")
plt.show()
일반고객 쿠폰미사용
plt.figure(figsize=(15,5))
plt.subplot(1, 3, 1)
t2 = t[t['category_title']=='프로그래밍']
plt.title("프로그래밍")
plt.xticks(rotation='vertical')
sns.histplot(t2, x="revenue", bins=20)
plt.subplot(1, 3, 2)
t2 = t[t['category_title']=='데이터사이언스']
plt.title("데이터사이언스")
plt.xticks(rotation='vertical')
sns.histplot(t2, x="revenue", bins=20)
plt.subplot(1, 3, 3)
t2 = t[t['category_title']=='마케팅']
plt.title("마케팅")
plt.xticks(rotation='vertical')
sns.histplot(t2, x="revenue", bins=20)
<matplotlib.axes._subplots.AxesSubplot at 0x7f1760596350>
t[t['category_title']=='프로그래밍']['revenue'].mean()
135392.40360951598
t[t['category_title']=='데이터사이언스']['revenue'].mean()
156380.5033809166
t[t['category_title']=='마케팅']['revenue'].mean()
141928.50574712644
t = pt[~pt["coupon_title"].isnull() & (pt["vip"]=='Normal')]
t2 = t.groupby("category_title").agg({"id": "count", "revenue": "sum"})
t2.drop(["비즈니스", "지식콘텐츠"], inplace=True) # 비즈니스 3건, 지식콘텐츠 1건
t2
| id | revenue | |
|---|---|---|
| category_title | ||
| 데이터사이언스 | 2274 | 197571200.0 |
| 디자인 | 2879 | 317568620.0 |
| 마케팅 | 1353 | 110505155.0 |
| 부동산/금융 | 960 | 115651950.0 |
| 업무생산성 | 2340 | 187682975.0 |
| 영상/3D | 2607 | 241862300.0 |
| 크리에이티브 | 19 | 1268600.0 |
| 투자/재테크 | 702 | 118909000.0 |
| 프로그래밍 | 6283 | 454700490.0 |
plt.figure(figsize=(12, 6))
colors = sns.color_palette('Set2')[0:8]
plt.subplot(1,2,1)
plt.pie(t2['id'], labels=t2.index, autopct='%.1f%%', startangle=260, colors=colors, counterclock=False, wedgeprops={'width': 0.7, 'edgecolor': 'w', 'linewidth': 5})
plt.xlabel(f"거래건수 비율\n 총 {t2['id'].sum()} 건")
plt.subplot(1,2,2)
plt.pie(t2['revenue'], labels=t2.index, autopct='%.1f%%', startangle=260, colors=colors, counterclock=False, wedgeprops={'width': 0.7, 'edgecolor': 'w', 'linewidth': 5})
plt.xlabel(f"수익률 비율\n 총 {t2['revenue'].astype(int).sum():,}원")
plt.show()
일반고객 쿠폰사용
plt.figure(figsize=(15,5))
plt.subplot(1, 3, 1)
t2 = t[t['category_title']=='프로그래밍']
plt.title('프로그래밍')
plt.xticks(rotation='vertical')
sns.histplot(t2, x="revenue", bins=20)
plt.subplot(1, 3, 2)
t2 = t[t['category_title']=='디자인']
plt.title('디자인')
plt.xticks(rotation='vertical')
sns.histplot(t2, x="revenue", bins=20)
plt.subplot(1, 3, 3)
t2 = t[t['category_title']=='영상/3D']
plt.title('영상/3D')
plt.xticks(rotation='vertical')
sns.histplot(t2, x="revenue", bins=20)
<matplotlib.axes._subplots.AxesSubplot at 0x7f1762a6f410>
t[t['category_title']=='프로그래밍']['revenue'].mean()
72369.96498487983
t[t['category_title']=='디자인']['revenue'].mean()
110305.18235498437
t[t['category_title']=='영상/3D']['revenue'].mean()
92774.18488684311
t = pt[~pt["coupon_title"].isnull() & (pt["vip"]=='Normal')]
t2 = t.groupby("customer_id").agg({"id": "count", "revenue": "sum"})
t3 = pt[pt["customer_id"].isin(t2.index)]
t2 = t3.groupby("customer_id").agg({"id": "count", "revenue": "sum"})
def func(x):
if x>=2:
return "나머지"
else:
return "1개구매"
t2["buy"] = t2['id'].apply(func)
t3 = t2.groupby("buy").agg({"id": "count", "revenue": "sum"})
t3
| id | revenue | |
|---|---|---|
| buy | ||
| 1개구매 | 12935 | 1.295708e+09 |
| 나머지 | 3869 | 7.729333e+08 |
plt.figure(figsize=(12, 6))
colors = sns.color_palette('Set2')[0:8]
plt.subplot(1,2,1)
plt.pie(t3['id'], labels=t3.index, autopct='%.1f%%', startangle=260, colors=colors, counterclock=False, wedgeprops={'width': 0.7, 'edgecolor': 'w', 'linewidth': 5})
plt.xlabel(f"거래건수 비율\n 총 {t3['id'].sum()} 건")
plt.subplot(1,2,2)
plt.pie(t3['revenue'], labels=t3.index, autopct='%.1f%%', startangle=260, colors=colors, counterclock=False, wedgeprops={'width': 0.7, 'edgecolor': 'w', 'linewidth': 5})
plt.xlabel(f"수익률 비율\n 총 {t3['revenue'].astype(int).sum():,}원")
plt.show()
t = pt[~pt["coupon_title"].isnull() & (pt["vip"]=='Normal')]
def func(x):
if "2021-04-01"<=x and x<"2021-05-01":
return "4월"
elif "2021-05-01"<=x and x<"2021-06-01":
return "5월"
elif "2021-06-01"<=x and x<"2021-07-01":
return "6월"
elif "2021-07-01"<=x and x<"2021-08-01":
return "7월"
elif "2021-08-01"<=x and x<"2021-09-01":
return "8월"
elif "2021-09-01"<=x and x<"2021-10-01":
return "9월"
else:
return "나머지"
t["coupon_month"] = t['completed_at'].apply(func)
/usr/local/lib/python3.7/dist-packages/ipykernel_launcher.py:17: SettingWithCopyWarning: A value is trying to be set on a copy of a slice from a DataFrame. Try using .loc[row_indexer,col_indexer] = value instead See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy
t2 = t.groupby('coupon_month').agg({"revenue": "sum", "id": "count"})
t2.drop("나머지", inplace=True)
t2
| revenue | id | |
|---|---|---|
| coupon_month | ||
| 4월 | 295855795.0 | 4242 |
| 5월 | 325842780.0 | 3616 |
| 6월 | 77939980.0 | 1511 |
| 7월 | 247955950.0 | 2102 |
| 8월 | 462762750.0 | 4031 |
| 9월 | 252305700.0 | 2543 |
plt.figure(figsize=(12, 6))
colors = sns.color_palette('Set2')[0:8]
plt.subplot(1,2,1)
plt.pie(t2['id'], labels=t2.index, autopct='%.1f%%', startangle=260, colors=colors, counterclock=False, wedgeprops={'width': 0.7, 'edgecolor': 'w', 'linewidth': 5})
plt.xlabel(f"거래건수 비율\n 총 {t2['id'].sum()} 건")
plt.subplot(1,2,2)
plt.pie(t2['revenue'], labels=t2.index, autopct='%.1f%%', startangle=260, colors=colors, counterclock=False, wedgeprops={'width': 0.7, 'edgecolor': 'w', 'linewidth': 5})
plt.xlabel(f"수익률 비율\n 총 {t2['revenue'].astype(int).sum():,}원")
plt.show()
t = pt[~pt["coupon_title"].isnull() & (pt["vip"]=='Normal')]
def func(x):
if x.startswith("4월"):
return "4월"
elif x.startswith("5월"):
return "5월"
elif x.startswith("6월"):
return "6월"
elif x.startswith("7월"):
return "7월"
elif x.startswith("8월"):
return "8월"
else:
return "해당없음"
t["coupon_month"] = t['coupon_title'].apply(func)
/usr/local/lib/python3.7/dist-packages/ipykernel_launcher.py:15: SettingWithCopyWarning: A value is trying to be set on a copy of a slice from a DataFrame. Try using .loc[row_indexer,col_indexer] = value instead See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy from ipykernel import kernelapp as app
t2 = t.groupby('coupon_month').agg({"revenue": "sum", "id": "count"})
t2.drop("해당없음", inplace=True)
t2
| revenue | id | |
|---|---|---|
| coupon_month | ||
| 4월 | 18235700.0 | 1042 |
| 5월 | 15365780.0 | 865 |
| 6월 | 9389200.0 | 135 |
| 7월 | 18123950.0 | 788 |
| 8월 | 26377650.0 | 1024 |
plt.figure(figsize=(12, 6))
colors = sns.color_palette('Set2')[0:6]
plt.subplot(1,2,1)
plt.pie(t2['id'], labels=t2.index, autopct='%.1f%%', startangle=260, colors=colors, counterclock=False, wedgeprops={'width': 0.7, 'edgecolor': 'w', 'linewidth': 5})
plt.xlabel(f"거래건수 비율")
plt.subplot(1,2,2)
plt.pie(t2['revenue'], labels=t2.index, autopct='%.1f%%', startangle=260, colors=colors, counterclock=False, wedgeprops={'width': 0.7, 'edgecolor': 'w', 'linewidth': 5})
plt.xlabel(f"수익률 비율")
plt.show()
6월이 수입이 많아서 1+1 페이백 이벤트 등 쿠폰 이벤트를 안한거같다
4월과 8월 거래건수는 비슷한데 수익차이가 약 1.85배난다
-> 4월, 8월 데이터 집중 분석
# 'X월' 쿠폰
print(t[t["coupon_month"] == '4월']['coupon_title'].value_counts())
print()
print(t[t["coupon_month"] == '5월']['coupon_title'].value_counts())
print()
print(t[t["coupon_month"] == '6월']['coupon_title'].value_counts())
print()
print(t[t["coupon_month"] == '7월']['coupon_title'].value_counts())
print()
print(t[t["coupon_month"] == '8월']['coupon_title'].value_counts())
4월 1+1 페이백 이벤트 쿠폰 1042 Name: coupon_title, dtype: int64 5월 페이백 프로모션 쿠폰 850 5월 5일 어른이날 기념 5%쿠폰 15 Name: coupon_title, dtype: int64 6월 반값특가 프로모션 쿠폰 135 Name: coupon_title, dtype: int64 7월 100% 페이백 프로모션 쿠폰 787 7월 100% 페이백 프로모션 쿠폰_복구 1 Name: coupon_title, dtype: int64 8월 1+1 프로모션 쿠폰 1024 Name: coupon_title, dtype: int64
t = pt[~pt["coupon_title"].isnull() & (pt["vip"]=='Normal')]
def func(x):
if x.startswith("4월"):
return "4월"
elif x.startswith("5월"):
return "5월"
elif x.startswith("6월"):
return "6월"
elif x.startswith("7월"):
return "7월"
elif x.startswith("8월"):
return "8월"
else:
return "해당없음"
t["coupon_month"] = t['coupon_title'].apply(func)
/usr/local/lib/python3.7/dist-packages/ipykernel_launcher.py:15: SettingWithCopyWarning: A value is trying to be set on a copy of a slice from a DataFrame. Try using .loc[row_indexer,col_indexer] = value instead See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy from ipykernel import kernelapp as app
t3 = t[(t['coupon_month']=="4월")|(t['coupon_month']=="8월")]
# 4월, 8월의 'X월' 쿠폰 사용 빈도
plt.figure(figsize=(10,6))
sns.scatterplot(data=t3, x="sale_price", y="revenue", hue="coupon_month")
<matplotlib.axes._subplots.AxesSubplot at 0x7f17620fcc90>
# 사업, 프로그램별 구매데이터 합치기
df_b2 = pd.concat([df_b2b, df_b2g])
df_program = pd.concat([df_finish, df_camp, df_school])
t = df_program.groupby("customer_id").agg({"revenue": "sum", "id": "count"})
t[(t["revenue"]>=400000)].sort_values(by=["revenue", "id"], ascending=False)
| revenue | id | |
|---|---|---|
| customer_id | ||
| 509993 | 1902600.0 | 2 |
| 42009 | 1821000.0 | 2 |
| 29094 | 1800000.0 | 1 |
| 277943 | 1620000.0 | 1 |
| 53748 | 1530000.0 | 1 |
| ... | ... | ... |
| 64646 | 400000.0 | 1 |
| 120463 | 400000.0 | 1 |
| 430107 | 400000.0 | 1 |
| 486036 | 400000.0 | 1 |
| 505754 | 400000.0 | 1 |
514 rows × 2 columns
# vip고객 분리
t = pt.groupby("customer_id").agg({"revenue": "sum", "id": "count"})
t2 = t[(t["revenue"]>=400000)].sort_values(by=["revenue", "id"], ascending=False)
t2_r = t[(t["revenue"]<400000)].sort_values(by=["revenue", "id"], ascending=False)
t2
| revenue | id | |
|---|---|---|
| customer_id | ||
| 98685 | 7040750.0 | 53 |
| 50769 | 4805950.0 | 38 |
| 40783 | 4424095.0 | 34 |
| 20784 | 3445050.0 | 26 |
| 72501 | 3235150.0 | 20 |
| ... | ... | ... |
| 661840 | 401000.0 | 2 |
| 526317 | 400500.0 | 4 |
| 644372 | 400500.0 | 3 |
| 457708 | 400200.0 | 4 |
| 71588 | 400000.0 | 2 |
1561 rows × 2 columns
# vip 고객 라벨링
def func(x):
if x in t2.index:
return "vip"
else:
return "normal"
pt['vip'] = pt["customer_id"].apply(func)
# 사업, 프로그램 라벨링
df_b2['vip'] = "사업"
df_program['vip'] = "프로그램"
df = pd.concat([pt, df_b2, df_program]).sort_values(by=["id"])
t5 = df.groupby('vip').agg({"id": "count", "revenue": "sum"})
# VIP 특징
plt.figure(figsize=(15, 10))
plt.subplot(1,3,1)
plt.pie([len(t2_r), len(t2), len(df_b2), len(df_program)], labels=["Normal", "VIP", "사업", "프로그램"], autopct='%.1f%%', startangle=260, counterclock=False, wedgeprops={'width': 0.7, 'edgecolor': 'w', 'linewidth': 5})
plt.xlabel("고객수 비율")
plt.subplot(1,3,2)
plt.pie(t5['id'], labels=t5.index, autopct='%.1f%%', startangle=260, counterclock=False, wedgeprops={'width': 0.7, 'edgecolor': 'w', 'linewidth': 5})
plt.xlabel("거래건수 비율")
plt.subplot(1,3,3)
plt.pie(t5['revenue'], labels=t5.index, autopct='%.1f%%', startangle=260, counterclock=False, wedgeprops={'width': 0.7, 'edgecolor': 'w', 'linewidth': 5})
plt.xlabel("수익량 비율")
plt.show()
t5
| id | revenue | |
|---|---|---|
| vip | ||
| normal | 40079 | 4.683223e+09 |
| vip | 5872 | 9.876963e+08 |
| 사업 | 1617 | 2.023714e+09 |
| 프로그램 | 1648 | 5.453241e+08 |
# 1502명중 450명이 개인고객으로 전환
from_program = pt[pt["customer_id"].isin(df_program["customer_id"])]
len(df_program["customer_id"].unique())
1502
len(from_program["customer_id"].unique())
450
프로그램 참여자의 경우 일반고객으로 전환된 사람이 매우 많다.
# 이중 vip 고객이 된 사람 탐색
len(from_program[from_program["vip"]=="vip"]["customer_id"].unique())
79
# 프로그램에서 넘어온 모든 구매자들의 첫 구매가 프로그램이였는지 확인
first = pd.DataFrame([])
for id in from_program["customer_id"].unique():
first = pd.concat([df[df["customer_id"]==id].head(1), first])
# 온라인 완주반 프로그램을 통해 일반고객으로 전환된 고객이 다수 측정됨
first["format"].value_counts()
온라인 완주반 179 올인원 171 스쿨 온라인 85 RED 6 하루10분컷 6 캠프 1 MBA 1 이벤트 1 Name: format, dtype: int64
# 1502명중 97명이 개인고객으로 전환
from_b2 = pt[pt["customer_id"].isin(df_b2["customer_id"])]
len(df_b2["customer_id"].unique())
1502
len(from_b2["customer_id"].unique())
97
b2사업 결제데이터의 경우
-> 비율이 상대적으로 적게 나옴
# b2사업 참여자 중 vip 고객이 된 사람의 수
len(from_b2[from_b2["vip"]=="vip"]["customer_id"].unique())
7
마찬가지로 b2결제 내역까지 합쳐서 vip를 선정했다면 더 많다는 결과가 나왔을 것으로 예상
# b2 사업에서 넘어온 모든 구매자들의 첫 구매가 b2 사업이였는지 확인
first = pd.DataFrame([])
for id in from_b2["customer_id"].unique():
first = pd.concat([df[df["customer_id"]==id].head(1), first])
# 기존 고객인 경우가 대다수
first["format"].value_counts()
올인원 66 B2B 12 B2G 7 하루10분컷 5 RED 3 온라인 완주반 2 B2B 온라인 1 이벤트 1 Name: format, dtype: int64
df_etc = pd.concat([df_b2, df_program])
# 사업/프로그램 참여 고객들중 우선 해당 구매가 패스트 캠퍼스에서의 첫 구매인 고객들을 뽑아오자.
first = pd.DataFrame([])
for id in df_etc["customer_id"].unique():
first = pd.concat([df[df["customer_id"]==id].head(1), first])
lst = ["B2B", "B2G", "B2B 온라인", "온라인 완주반", '캠프', '스쿨 온라인', '스쿨']
etc_new = first[first["format"].isin(lst)]
이렇게 새로 만들어진 데이터에서 새로운 컬럼(moved)을 생성
# 전환고객 추출
from_etc = pt[pt["customer_id"].isin(etc_new["customer_id"])]
# 라벨링
def func(x):
if x in from_etc["customer_id"].unique():
return True
else:
return False
etc_new['moved'] = etc_new["customer_id"].apply(func)
/usr/local/lib/python3.7/dist-packages/ipykernel_launcher.py:8: SettingWithCopyWarning: A value is trying to be set on a copy of a slice from a DataFrame. Try using .loc[row_indexer,col_indexer] = value instead See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy
# 변환 확인
etc_new["moved"].value_counts()
False 2453 True 285 Name: moved, dtype: int64
t = pd.pivot_table(data=etc_new, index=["format"], values ="id", columns=["moved"], aggfunc=["count"])
t["ratio"] = t[('count', True)] / t[('count', False)] *100
t
| count | ratio | ||
|---|---|---|---|
| moved | False | True | |
| format | |||
| B2B | 258.0 | 12.0 | 4.651163 |
| B2B 온라인 | 921.0 | 1.0 | 0.108578 |
| B2G | 222.0 | 7.0 | 3.153153 |
| 스쿨 | 10.0 | NaN | NaN |
| 스쿨 온라인 | 157.0 | 85.0 | 54.140127 |
| 온라인 완주반 | 873.0 | 179.0 | 20.504009 |
| 캠프 | 12.0 | 1.0 | 8.333333 |
plt.figure(figsize=(8,5))
sns.countplot(data = etc_new, x="format", hue="moved")
plt.show()
일반고객으로 가장 많은 전환이 이루어진 것은 온라인 완주반(179명)
일반고객으로 가장 많은 비율이 전환된 것은 스쿨 온라인(53.5%)
# 사업/프로그램 구매 데이터 기준 카테고리 분석
t = pd.pivot_table(data=etc_new, index = ['category_title'], values=['id'], aggfunc = "count").reset_index()
plt.figure(figsize=(5,7))
colors = sns.color_palette('Set2')[0:5]
plt.pie(t['id'], labels=t['category_title'], autopct='%.1f%%', startangle=260, colors=colors, counterclock=False, textprops={'fontsize': 10
}, wedgeprops={'width': 0.7, 'edgecolor': 'w', 'linewidth': 5})
plt.xlabel(f"총 {t['id'].sum()}건 구매")
plt.show()
카테고리 "교육"이 세분화 되지 않고 큰 부분을 차지해 분석의 의미가 크지 않다.
# 전환고객의 카테고리 분석
pd.pivot_table(data=from_etc, index=["category_title", "subcategory_title"], values=["revenue"], aggfunc=["count", "sum"])
| count | sum | ||
|---|---|---|---|
| revenue | revenue | ||
| category_title | subcategory_title | ||
| 데이터사이언스 | 데이터분석 | 29 | 3303650.0 |
| 데이터사이언스 | 6 | 1802000.0 | |
| 데이터엔지니어링 | 8 | 2273800.0 | |
| 딥러닝/인공지능 | 31 | 3564800.0 | |
| 머신러닝 | 12 | 1559300.0 | |
| 디자인 | UX/UI | 7 | 881000.0 |
| 디자인툴 | 9 | 1261100.0 | |
| 시각디자인 | 3 | 382000.0 | |
| 일러스트 | 5 | 695000.0 | |
| 마케팅 | SNS마케팅 | 2 | 75000.0 |
| 글쓰기/카피라이팅 | 3 | 424000.0 | |
| 데이터마케팅 | 5 | 573500.0 | |
| 디지털마케팅 | 3 | 689000.0 | |
| 마케팅 | 1 | 45000.0 | |
| 부동산/금융 | 금융/투자 실무 | 4 | 550100.0 |
| 부동산/금융 | 1 | 299000.0 | |
| 회계/재무/세무 | 10 | 1735300.0 | |
| 업무생산성 | PPT/보고서 | 15 | 1489225.0 |
| 리더십 | 4 | 509400.0 | |
| 업무생산성 | 13 | 265825.0 | |
| 업무자동화 | 7 | 338500.0 | |
| 엑셀/VBA | 9 | 944000.0 | |
| 커뮤니케이션 | 1 | 14200.0 | |
| 영상/3D | VFX | 4 | 501200.0 |
| 게임 그래픽 | 2 | 304200.0 | |
| 영상 편집 | 8 | 633000.0 | |
| 크리에이티브 | 크리에이티브 | 3 | 818000.0 |
| 투자/재테크 | 부동산 투자 | 1 | 15500.0 |
| 주식 투자 | 8 | 1467000.0 | |
| 프로그래밍 | DevOps | 31 | 3860900.0 |
| 개발자 커리어 | 49 | 4311000.0 | |
| 게임 | 5 | 403500.0 | |
| 모바일앱 | 21 | 2353300.0 | |
| 백엔드 개발 | 91 | 10391600.0 | |
| 코딩 입문 | 10 | 911600.0 | |
| 프로그래밍 | 23 | 4348100.0 | |
| 프론트엔드 개발 | 69 | 8308550.0 |
t = pd.pivot_table(data=from_etc, index = ['category_title'], values=['id'], aggfunc = "count").reset_index()
plt.figure(figsize=(5,7))
colors = sns.color_palette('Set2')[0:5]
plt.pie(t['id'], labels=t['category_title'], autopct='%.1f%%', textprops={'fontsize': 12}, startangle=260, colors=colors, counterclock=False, wedgeprops={'width': 0.7, 'edgecolor': 'w', 'linewidth': 5})
plt.xlabel(f"총 {t['id'].sum()}건 구매")
plt.show()
t = pd.pivot_table(data=from_etc, index = ['category_title','subcategory_title'], values=['id'], aggfunc = "count").reset_index()
ct = list(t['category_title'].unique())
plt.figure(figsize=(12,18))
colors = sns.color_palette('Set2')[0:5]
for i, title in enumerate(ct):
plt.subplot(3, 3, i+1)
plt.title(f"{title}")
t1 = t[t['category_title']==title]
plt.pie(t1['id'], labels=t1['subcategory_title'], autopct='%.1f%%', startangle=260, colors=colors, counterclock=False, wedgeprops={'width': 0.7, 'edgecolor': 'w', 'linewidth': 5})
plt.xlabel(f"총 {t1['id'].sum()}건 구매")
plt.show()
t = pd.pivot_table(data=from_etc, index = ['category_title'], values=['revenue'], aggfunc = "sum").reset_index()
plt.figure(figsize=(5,6))
colors = sns.color_palette('Set2')[0:5]
plt.pie(t['revenue'], labels=t['category_title'], autopct='%.1f%%', startangle=260, colors=colors, counterclock=False, wedgeprops={'width': 0.7, 'edgecolor': 'w', 'linewidth': 5})
plt.xlabel(f"총 {t['revenue'].sum()/10000}만원 구매")
plt.show()
t = pd.pivot_table(data=from_etc, index = ['category_title','subcategory_title'], values=['revenue'], aggfunc = "sum").reset_index()
ct = list(t['category_title'].unique())
plt.figure(figsize=(12,18))
colors = sns.color_palette('Set2')[0:5]
for i, title in enumerate(ct):
plt.subplot(3, 3, i+1)
plt.title(f"{title}")
t1 = t[t['category_title']==title]
plt.pie(t1['revenue'], labels=t1['subcategory_title'], autopct='%.1f%%', startangle=260, colors=colors, counterclock=False, wedgeprops={'width': 0.7, 'edgecolor': 'w', 'linewidth': 5})
plt.xlabel(f"총 {t1['revenue'].sum()/10000}만원 결제")
plt.show()
프로그래밍, 데이터사이언스 카테고리에 관심을 가지는 전환고객의 비율이 대다수이다.
해당 카테고리에서의 결제액도 대다수를 차지한다.
# 쿠폰 사용여부 라벨링
from_etc["coupon_used"] = True
from_etc.loc[from_etc["coupon_title"].isnull(),"coupon_used"] = False
/usr/local/lib/python3.7/dist-packages/ipykernel_launcher.py:2: SettingWithCopyWarning: A value is trying to be set on a copy of a slice from a DataFrame. Try using .loc[row_indexer,col_indexer] = value instead See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy /usr/local/lib/python3.7/dist-packages/pandas/core/indexing.py:1817: SettingWithCopyWarning: A value is trying to be set on a copy of a slice from a DataFrame. Try using .loc[row_indexer,col_indexer] = value instead See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy self._setitem_single_column(loc, value, pi)
# pt 데이터 쿠폰 사용여부 라벨링
pt["coupon_used"] = True
pt.loc[pt["coupon_title"].isnull(),"coupon_used"] = False
t0 = from_etc.groupby("coupon_used").agg({"id": "count"})
t00 = pt.groupby("coupon_used").agg({"id": "count"})
pt.info()
<class 'pandas.core.frame.DataFrame'> Int64Index: 45951 entries, 4 to 105418 Data columns (total 23 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 id 45951 non-null float64 1 customer_id 45951 non-null int64 2 course_id 43973 non-null float64 3 type 45951 non-null object 4 state 45951 non-null object 5 course_title 45951 non-null object 6 category_title 45951 non-null object 7 format 45951 non-null object 8 completed_at 45951 non-null object 9 transaction_amount 45951 non-null float64 10 coupon_title 21451 non-null object 11 coupon_discount_amount 21451 non-null float64 12 sale_price 45929 non-null float64 13 tax_free_amount 45929 non-null float64 14 pg 39400 non-null object 15 method 45951 non-null object 16 subcategory_title 45951 non-null object 17 marketing_start_at 39026 non-null datetime64[ns] 18 purchased 45951 non-null bool 19 revenue 45951 non-null float64 20 vip 45951 non-null object 21 pre_vip 45951 non-null bool 22 coupon_used 45951 non-null bool dtypes: bool(3), datetime64[ns](1), float64(7), int64(1), object(11) memory usage: 7.5+ MB
plt.figure(figsize=(8, 6))
colors = sns.color_palette('Set2')[0:8]
plt.subplot(1,2,1)
plt.pie(t0['id'], labels=t0.index, autopct='%.1f%%', startangle=260, colors=colors, counterclock=False, wedgeprops={'width': 0.7, 'edgecolor': 'w', 'linewidth': 5})
plt.xlabel(f"전환고객 쿠폰 사용 비율\n 총 {t0['id'].sum()} 건")
plt.subplot(1,2,2)
plt.pie(t00['id'], labels=t00.index, autopct='%.1f%%', startangle=260, colors=colors, counterclock=False, wedgeprops={'width': 0.7, 'edgecolor': 'w', 'linewidth': 5})
plt.xlabel(f"일반고객 쿠폰 사용 비율\n 총 {t00['id'].sum()} 건")
plt.show()
일반고객의 쿠폰 사용 비율과 전환고객의 쿠폰 사용 비율 사이에는 큰 차이가 없다.
쿠폰이 전환 고객에 미치는 영향을 다른 관점에서 보아야 할듯 하다.
# 비슷하게 쿠폰 사용 고객 비율을 계산해 보자
t0 = from_etc.groupby("customer_id").agg({"coupon_used": "sum"})
t00 = pt.groupby("customer_id").agg({"coupon_used": "sum"})
def func(x):
if x ==0 :
return False
else:
return True
t0["coupon_used"] = t0["coupon_used"].apply(func)
t00["coupon_used"] = t00["coupon_used"].apply(func)
t0 = from_etc.groupby("coupon_used").agg({"customer_id": "count"})
t00 = pt.groupby("coupon_used").agg({"customer_id": "count"})
plt.figure(figsize=(8, 6))
colors = sns.color_palette('Set2')[0:8]
plt.subplot(1,2,1)
plt.pie(t0['customer_id'], labels=t0.index, autopct='%.1f%%', startangle=260, colors=colors, counterclock=False, wedgeprops={'width': 0.7, 'edgecolor': 'w', 'linewidth': 5})
plt.xlabel(f"쿠폰 사용 전환고객 비율\n 총 {t0['customer_id'].sum()} 건")
plt.subplot(1,2,2)
plt.pie(t00['customer_id'], labels=t00.index, autopct='%.1f%%', startangle=260, colors=colors, counterclock=False, wedgeprops={'width': 0.7, 'edgecolor': 'w', 'linewidth': 5})
plt.xlabel(f"쿠폰 사용 일반고객 비율\n 총 {t00['customer_id'].sum()} 명")
plt.show()
마찬가지로 쿠폰 사용 일반고객 비율과 쿠폰 사용 전환고객 비율 사이에는 큰 차이가 없다.
전략